/** * Test for SF bug #1309731. * * @cdk.bug 1309731 */ @Test public void testModelBuilder3D_keepChemObjectIDs() throws Exception { ModelBuilder3D mb3d = ModelBuilder3D.getInstance(); IMolecule methanol = new org.openscience.cdk.Molecule(); IChemObjectBuilder builder = methanol.getBuilder(); IAtom carbon1 = builder.newInstance(IAtom.class, "C"); carbon1.setID("carbon1"); methanol.addAtom(carbon1); for (int i = 0; i < 3; i++) { IAtom hydrogen = builder.newInstance(IAtom.class, "H"); methanol.addAtom(hydrogen); methanol.addBond(builder.newInstance(IBond.class, carbon1, hydrogen, IBond.Order.SINGLE)); } IAtom oxygen1 = builder.newInstance(IAtom.class, "O"); oxygen1.setID("oxygen1"); methanol.addAtom(oxygen1); methanol.addBond(builder.newInstance(IBond.class, carbon1, oxygen1, IBond.Order.SINGLE)); IAtom hydrogen = builder.newInstance(IAtom.class, "H"); methanol.addAtom(hydrogen); methanol.addBond(builder.newInstance(IBond.class, hydrogen, oxygen1, IBond.Order.SINGLE)); Assert.assertEquals(6, methanol.getAtomCount()); Assert.assertEquals(5, methanol.getBondCount()); mb3d.generate3DCoordinates(methanol, false); checkAverageBondLength(methanol); Assert.assertEquals("carbon1", carbon1.getID()); Assert.assertEquals("oxygen1", oxygen1.getID()); }
/** Converts an Atom to a MSML Atom element */ protected AtomType convertAtom(IAtom atom, String parentID) { AtomType atomElement = new AtomType(); String id = ""; if (atom.getID() != null) { id = atom.getID(); } else { id = Integer.toString(atom.hashCode()); } String atomID = parentID + PREFIX_ATOM + id; atomElement.setId(atomID); atomElement.setCustomId("" + id); // atom name atomElement.setTitle(atom.getAtomTypeName()); // element name atomElement.setElementType(atom.getSymbol()); double x, y, z; // set choords if (atom.getPoint3d() != null) { x = atom.getPoint3d().x; y = atom.getPoint3d().y; z = atom.getPoint3d().z; } else { // what if mol in 2d? -> has to use getPoint2d x = atom.getPoint2d().x; y = atom.getPoint2d().y; z = 0.0; } if (atom.getFormalCharge() != null) { atomElement.setFormalCharge(BigInteger.valueOf(atom.getFormalCharge())); } atomElement.setX3(new Float(x)); atomElement.setY3(new Float(y)); atomElement.setZ3(new Float(z)); return atomElement; }
@Test public void testBond() throws Exception { String cmlString = "<molecule id='m1'><atomArray><atom id='a1'/><atom id='a2'/></atomArray><bondArray><bond id='b1' atomRefs2='a1 a2'/></bondArray></molecule>"; IChemFile chemFile = parseCMLString(cmlString); IMolecule mol = checkForSingleMoleculeFile(chemFile); Assert.assertEquals(2, mol.getAtomCount()); Assert.assertEquals(1, mol.getBondCount()); org.openscience.cdk.interfaces.IBond bond = mol.getBond(0); Assert.assertEquals(2, bond.getAtomCount()); IAtom atom1 = bond.getAtom(0); IAtom atom2 = bond.getAtom(1); Assert.assertEquals("a1", atom1.getID()); Assert.assertEquals("a2", atom2.getID()); }
@Test public void testAtomId3() throws Exception { String cmlString = "<molecule id='m1'><atomArray atomID='a1 a2 a3'/></molecule>"; IChemFile chemFile = parseCMLString(cmlString); IMolecule mol = checkForSingleMoleculeFile(chemFile); Assert.assertEquals(3, mol.getAtomCount()); IAtom atom = mol.getAtom(1); Assert.assertEquals("a2", atom.getID()); }
/** * Read a Reaction from a file in MDL RXN format * * @return The Reaction that was read from the MDL file. */ private IReaction readReaction(IChemObjectBuilder builder) throws CDKException { IReaction reaction = builder.newReaction(); try { input.readLine(); // first line should be $RXN input.readLine(); // second line input.readLine(); // third line input.readLine(); // fourth line } catch (IOException exception) { logger.debug(exception); throw new CDKException("Error while reading header of RXN file", exception); } int reactantCount = 0; int productCount = 0; try { String countsLine = input.readLine(); /* this line contains the number of reactants and products */ StringTokenizer tokenizer = new StringTokenizer(countsLine); reactantCount = Integer.valueOf(tokenizer.nextToken()).intValue(); logger.info("Expecting " + reactantCount + " reactants in file"); productCount = Integer.valueOf(tokenizer.nextToken()).intValue(); logger.info("Expecting " + productCount + " products in file"); } catch (Exception exception) { logger.debug(exception); throw new CDKException("Error while counts line of RXN file", exception); } // now read the reactants try { for (int i = 1; i <= reactantCount; i++) { StringBuffer molFile = new StringBuffer(); input.readLine(); // announceMDLFileLine String molFileLine = ""; do { molFileLine = input.readLine(); molFile.append(molFileLine); molFile.append(System.getProperty("line.separator")); } while (!molFileLine.equals("M END")); // read MDL molfile content // Changed this to mdlv2000 reader MDLV2000Reader reader = new MDLV2000Reader(new StringReader(molFile.toString()), super.mode); IMolecule reactant = (IMolecule) reader.read(builder.newMolecule()); // add reactant reaction.addReactant(reactant); } } catch (CDKException exception) { // rethrow exception from MDLReader throw exception; } catch (Exception exception) { logger.debug(exception); throw new CDKException("Error while reading reactant", exception); } // now read the products try { for (int i = 1; i <= productCount; i++) { StringBuffer molFile = new StringBuffer(); input.readLine(); // String announceMDLFileLine = String molFileLine = ""; do { molFileLine = input.readLine(); molFile.append(molFileLine); molFile.append(System.getProperty("line.separator")); } while (!molFileLine.equals("M END")); // read MDL molfile content MDLV2000Reader reader = new MDLV2000Reader(new StringReader(molFile.toString())); IMolecule product = (IMolecule) reader.read(builder.newMolecule()); // add reactant reaction.addProduct(product); } } catch (CDKException exception) { // rethrow exception from MDLReader throw exception; } catch (Exception exception) { logger.debug(exception); throw new CDKException("Error while reading products", exception); } // now try to map things, if wanted logger.info("Reading atom-atom mapping from file"); // distribute all atoms over two AtomContainer's IAtomContainer reactingSide = builder.newAtomContainer(); java.util.Iterator molecules = reaction.getReactants().molecules().iterator(); while (molecules.hasNext()) { reactingSide.add((IMolecule) molecules.next()); } IAtomContainer producedSide = builder.newAtomContainer(); molecules = reaction.getProducts().molecules().iterator(); while (molecules.hasNext()) { producedSide.add((IMolecule) molecules.next()); } // map the atoms int mappingCount = 0; // IAtom[] reactantAtoms = reactingSide.getAtoms(); // IAtom[] producedAtoms = producedSide.getAtoms(); for (int i = 0; i < reactingSide.getAtomCount(); i++) { for (int j = 0; j < producedSide.getAtomCount(); j++) { IAtom eductAtom = reactingSide.getAtom(i); IAtom productAtom = producedSide.getAtom(j); if (eductAtom.getID() != null && eductAtom.getID().equals(productAtom.getID())) { reaction.addMapping(builder.newMapping(eductAtom, productAtom)); mappingCount++; break; } } } logger.info("Mapped atom pairs: " + mappingCount); return reaction; }
@Override public BoundsTree layout(IAtom atom, Graphics2D g) { Rectangle2D idBounds; this.currentObject = atom; String id = atom.getID(); IAtomContainer molecule = null; if (this.parent != null) { molecule = (IAtomContainer) this.parent.getCurrentObject(); } this.boundsTree = new BoundsTree(atom.getID()); if (molecule == null || this.shouldDraw(atom, molecule)) { Integer implicitHydrogenCount; this.boundsTree.add(id + ":symbol", this.layoutAtomSymbol(atom, g)); if (this.isCharged(atom)) { Rectangle2D chargeBounds = this.layoutCharge(atom, g); this.boundsTree.add(id + ":charge", chargeBounds); } if (this.params.drawImplicitHydrogens && (implicitHydrogenCount = atom.getImplicitHydrogenCount()) != null && implicitHydrogenCount > 0) { int align = 1; if (molecule != null) { GeometryTools.getBestAlignmentForLabel((IAtomContainer) molecule, (IAtom) atom); } LabelManager.AnnotationPosition suggestedPosition = this.labelManager.alignmentToAnnotationPosition(align); if (atom.getSymbol().equals("O") && (molecule == null || molecule.getConnectedAtomsCount(atom) == 0)) { suggestedPosition = LabelManager.AnnotationPosition.W; } if (this.labelManager.isUsed(atom, suggestedPosition)) { suggestedPosition = this.labelManager.getNextSparePosition(atom); } this.labelManager.setUsedPosition(atom, suggestedPosition); Rectangle2D hBounds = this.layoutImplicitHydrogens(atom, implicitHydrogenCount, suggestedPosition, g); if (hBounds != null) { this.boundsTree.add(id + ":hs", hBounds); } } } else if (this.params.drawRS && this.chiralMap.containsKey(atom)) { this.boundsTree.add( id + ":chiral", this.layoutChiralSymbol(atom, this.chiralMap.get(atom), g)); } else { Point2d p = atom.getPoint2d(); this.boundsTree.add(id + ":symbol", new Point2D.Double(p.x, p.y)); } if (this.params.drawAtomID && molecule != null && (idBounds = this.layoutAtomID(atom, molecule, g)) != null) { this.boundsTree.add(id + ":id", idBounds); } if (this.params.drawLonePairs && molecule != null) { int lonePairCount = 0; for (ILonePair lonePair : molecule.lonePairs()) { if (!lonePair.contains(atom)) { continue; } ++lonePairCount; } if (lonePairCount > 0) { Stroke stroke = g.getStroke(); g.setStroke(new BasicStroke(0.05f)); this.layoutElectronPairs(atom, molecule, lonePairCount, g); g.setStroke(stroke); } } return this.boundsTree; }
public Rectangle2D layoutAtomID(IAtom atom, IAtomContainer container, Graphics2D g) { String atomID = atom.getID(); if (atomID == null) { return null; } g.setFont(this.atomSymbolFont); Point2d p = atom.getPoint2d(); Rectangle2D atomSymbolBounds = this.shouldDraw(atom, container) ? this.getTextBounds(g, atom.getSymbol()) : new Rectangle2D.Double(p.x, p.y, 1.0, 1.0); g.setFont(this.atomIDFont); Rectangle2D bounds = this.getTextBounds(g, atomID); Point2d pID = new Point2d(p); LabelManager.AnnotationPosition suggestedPosition = this.labelManager.alignmentToAnnotationPosition( GeometryTools.getBestAlignmentForLabelXY((IAtomContainer) container, (IAtom) atom)); LabelManager.AnnotationPosition pos = this.labelManager.isUsed(atom, suggestedPosition) ? this.labelManager.getNextSparePosition(atom) : suggestedPosition; double aW2 = atomSymbolBounds.getWidth() / 2.0; double bW2 = bounds.getWidth() / 2.0; double aH2 = atomSymbolBounds.getHeight() / 2.0; double bH2 = bounds.getHeight() / 2.0; if (null != pos) switch (pos) { case N: pID.y -= aH2 + bH2; break; case NE: pID.x += aW2 + bW2; pID.y -= aH2 + bH2; break; case E: pID.x += aW2 + bW2; break; case SE: pID.x += aW2 + bW2; pID.y += aH2 + bH2; break; case S: pID.y += aH2 + bH2; break; case SW: pID.x -= aW2 + bW2; pID.y += aH2 + bH2; break; case W: pID.x -= aW2 + bW2; break; case NW: pID.x -= aW2 + bW2; pID.y -= aH2 + bH2; break; default: pID.x += aW2 + bW2; break; } if (pos != null) { this.labelManager.setUsedPosition(atom, pos); } g.setFont(this.atomSymbolFont); return new Rectangle2D.Double( pID.x - bounds.getWidth() / 2.0, pID.y - bounds.getHeight() / 2.0, bounds.getWidth(), bounds.getHeight()); }