@TestMethod("testCalculate_IAtomContainer") public DescriptorValue calculate(IAtomContainer container) { // removeHydrogens does a deep copy, so no need to clone IAtomContainer localAtomContainer = AtomContainerManipulator.removeHydrogens(container); CDKAtomTypeMatcher matcher = CDKAtomTypeMatcher.getInstance(container.getBuilder()); Iterator<IAtom> atoms = localAtomContainer.atoms().iterator(); while (atoms.hasNext()) { IAtom atom = atoms.next(); IAtomType type; try { type = matcher.findMatchingAtomType(localAtomContainer, atom); AtomTypeManipulator.configure(atom, type); } catch (Exception e) { return getDummyDescriptorValue(new CDKException("Error in atom typing: " + e.getMessage())); } } CDKHydrogenAdder hAdder = CDKHydrogenAdder.getInstance(container.getBuilder()); try { hAdder.addImplicitHydrogens(localAtomContainer); } catch (CDKException e) { return getDummyDescriptorValue( new CDKException("Error in hydrogen addition: " + e.getMessage())); } List subgraph3 = order3(localAtomContainer); List subgraph4 = order4(localAtomContainer); List subgraph5 = order5(localAtomContainer); List subgraph6 = order6(localAtomContainer); double order3s = ChiIndexUtils.evalSimpleIndex(localAtomContainer, subgraph3); double order4s = ChiIndexUtils.evalSimpleIndex(localAtomContainer, subgraph4); double order5s = ChiIndexUtils.evalSimpleIndex(localAtomContainer, subgraph5); double order6s = ChiIndexUtils.evalSimpleIndex(localAtomContainer, subgraph6); double order3v, order4v, order5v, order6v; try { order3v = ChiIndexUtils.evalValenceIndex(localAtomContainer, subgraph3); order4v = ChiIndexUtils.evalValenceIndex(localAtomContainer, subgraph4); order5v = ChiIndexUtils.evalValenceIndex(localAtomContainer, subgraph5); order6v = ChiIndexUtils.evalValenceIndex(localAtomContainer, subgraph6); } catch (CDKException e) { return getDummyDescriptorValue( new CDKException("Error in substructure search: " + e.getMessage())); } DoubleArrayResult retval = new DoubleArrayResult(); retval.add(order3s); retval.add(order4s); retval.add(order5s); retval.add(order6s); retval.add(order3v); retval.add(order4v); retval.add(order5v); retval.add(order6v); return new DescriptorValue( getSpecification(), getParameterNames(), getParameters(), retval, getDescriptorNames()); }
/** * Place hydrogens connected to the provided atom <i>atom</i> using the specified * <i>bondLength</i>. * * @param container atom container * @param bondLength bond length to user * @throws IllegalArgumentException thrown if the <i>atom</i> or <i>container</i> was null or the * atom has connected atoms which have not been placed. */ @TestMethod("testNoConnections,testNullContainer,unplacedNonHydrogen") public void placeHydrogens2D(IAtomContainer container, IAtom atom, double bondLength) { if (container == null) throw new IllegalArgumentException("cannot place hydrogens, no container provided"); if (atom.getPoint2d() == null) throw new IllegalArgumentException("cannot place hydrogens on atom without coordinates"); logger.debug( "placing hydrogens connected to atom ", atom.getSymbol(), ": ", atom.getPoint2d()); logger.debug("bond length", bondLength); AtomPlacer atomPlacer = new AtomPlacer(); atomPlacer.setMolecule(container); List<IAtom> connected = container.getConnectedAtomsList(atom); IAtomContainer placed = container.getBuilder().newInstance(IAtomContainer.class); IAtomContainer unplaced = container.getBuilder().newInstance(IAtomContainer.class); // divide connected atoms into those which are have and haven't been placed for (final IAtom conAtom : connected) { if (conAtom.getPoint2d() == null) { if (conAtom.getSymbol().equals("H")) { unplaced.addAtom(conAtom); } else { throw new IllegalArgumentException( "cannot place hydrogens, atom has connected" + " non-hydrogens without coordinates"); } } else { placed.addAtom(conAtom); } } logger.debug("Atom placement before procedure:"); logger.debug("Centre atom ", atom.getSymbol(), ": ", atom.getPoint2d()); for (int i = 0; i < unplaced.getAtomCount(); i++) { logger.debug("H-" + i, ": ", unplaced.getAtom(i).getPoint2d()); } Point2d centerPlacedAtoms = GeometryTools.get2DCenter(placed); atomPlacer.distributePartners(atom, placed, centerPlacedAtoms, unplaced, bondLength); logger.debug("Atom placement after procedure:"); logger.debug("Centre atom ", atom.getSymbol(), ": ", atom.getPoint2d()); for (int i = 0; i < unplaced.getAtomCount(); i++) { logger.debug("H-" + i, ": ", unplaced.getAtom(i).getPoint2d()); } }
/** * 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; }
public String perceiveCDKAtomTypes(IMolecule mol) throws InvocationTargetException { ICDKMolecule cdkmol; try { cdkmol = cdk.asCDKMolecule(mol); } catch ( BioclipseException e ) { e.printStackTrace(); throw new InvocationTargetException( e, "Error while creating a ICDKMolecule" ); } IAtomContainer ac = cdkmol.getAtomContainer(); CDKAtomTypeMatcher cdkMatcher = CDKAtomTypeMatcher.getInstance(ac.getBuilder()); StringBuffer result = new StringBuffer(); int i = 1; for (IAtom atom : ac.atoms()) { IAtomType type = null; try { type = cdkMatcher.findMatchingAtomType(ac, atom); } catch ( CDKException e ) {} result.append(i).append(':').append( type != null ? type.getAtomTypeName() : "null" ).append('\n'); // FIXME: should use NEWLINE here i++; } return result.toString(); }
private void atomLayout(IAtomContainer atomContainer) { IMolecule mol = atomContainer.getBuilder().newInstance(IMolecule.class, atomContainer); sdg.setMolecule(mol, false); try { sdg.generateCoordinates(); } catch (Exception e) { e.printStackTrace(); } }
private void processAtomsBlock(int lineCount, IAtomContainer container) throws IOException { for (int i = 0; i < lineCount; i++) { String line = input.readLine(); int atomicNumber = Integer.parseInt(line.substring(7, 10).trim()); IAtom atom = container.getBuilder().newAtom(); atom.setAtomicNumber(atomicNumber); atom.setSymbol(Symbols.byAtomicNumber[atomicNumber]); container.addAtom(atom); } }
/** * Test to recognize if a IAtomContainer matcher correctly identifies the CDKAtomTypes. * * @param molecule The IAtomContainer to analyze * @throws CDKException */ private void makeSureAtomTypesAreRecognized(IAtomContainer molecule) throws CDKException { Iterator<IAtom> atoms = molecule.atoms().iterator(); CDKAtomTypeMatcher matcher = CDKAtomTypeMatcher.getInstance(molecule.getBuilder()); while (atoms.hasNext()) { IAtom nextAtom = atoms.next(); Assert.assertNotNull( "Missing atom type for: " + nextAtom, matcher.findMatchingAtomType(molecule, nextAtom)); } }
/** A unit test for JUnit */ @Test public void testAlanin() throws Exception { HydrogenPlacer hydrogenPlacer = new HydrogenPlacer(); IAtomContainer mol1 = new AtomContainer(); SmilesGenerator sg = new SmilesGenerator(); mol1.addAtom(new Atom("N", new Point2d(1, 0))); // 1 mol1.addAtom(new Atom("C", new Point2d(1, 2))); // 2 mol1.addAtom(new Atom("F", new Point2d(1, 2))); // 3 mol1.addAtom(new Atom("C", new Point2d(0, 0))); // 4 mol1.addAtom(new Atom("C", new Point2d(1, 4))); // 5 mol1.addAtom(new Atom("O", new Point2d(1, 5))); // 6 mol1.addAtom(new Atom("O", new Point2d(1, 6))); // 7 mol1.addBond(0, 1, IBond.Order.SINGLE); // 1 mol1.addBond(1, 2, IBond.Order.SINGLE, IBond.Stereo.UP); // 2 mol1.addBond(1, 3, IBond.Order.SINGLE, IBond.Stereo.DOWN); // 3 mol1.addBond(1, 4, IBond.Order.SINGLE); // 4 mol1.addBond(4, 5, IBond.Order.SINGLE); // 5 mol1.addBond(4, 6, IBond.Order.DOUBLE); // 6 addExplicitHydrogens(mol1); hydrogenPlacer.placeHydrogens2D(mol1, 1.0); IsotopeFactory ifac = IsotopeFactory.getInstance(mol1.getBuilder()); ifac.configureAtoms(mol1); String smiles1 = null; if (standAlone) { display(mol1); } smiles1 = sg.createSMILES(mol1, true, new boolean[mol1.getBondCount()]); if (standAlone) { System.err.println("SMILES 1: " + smiles1); } Assert.assertNotNull(smiles1); Assert.assertEquals("[H]OC(=O)[C@](F)(N([H])[H])C([H])([H])[H]", smiles1); mol1.getBond(1).setStereo(IBond.Stereo.DOWN); mol1.getBond(2).setStereo(IBond.Stereo.UP); smiles1 = sg.createSMILES(mol1, true, new boolean[mol1.getBondCount()]); if (standAlone) { System.err.println("SMILES 1: " + smiles1); } Assert.assertNotNull(smiles1); Assert.assertEquals("[H]OC(=O)[C@](F)(C([H])([H])[H])N([H])[H]", smiles1); }
private void fixHydrogenIsotopes(IAtomContainer molecule, IsotopeFactory isotopeFactory) { for (IAtom atom : AtomContainerManipulator.getAtomArray(molecule)) { if (atom instanceof IPseudoAtom) { IPseudoAtom pseudo = (IPseudoAtom) atom; if ("D".equals(pseudo.getLabel())) { IAtom newAtom = molecule.getBuilder().newInstance(IAtom.class, atom); newAtom.setSymbol("H"); newAtom.setAtomicNumber(1); isotopeFactory.configure(newAtom, isotopeFactory.getIsotope("H", 2)); AtomContainerManipulator.replaceAtomByAtom(molecule, atom, newAtom); } else if ("T".equals(pseudo.getLabel())) { IAtom newAtom = molecule.getBuilder().newInstance(IAtom.class, atom); newAtom.setSymbol("H"); newAtom.setAtomicNumber(1); isotopeFactory.configure(newAtom, isotopeFactory.getIsotope("H", 3)); AtomContainerManipulator.replaceAtomByAtom(molecule, atom, newAtom); } } } }
private void processBondsBlock(int lineCount, IAtomContainer container) throws IOException { for (int i = 0; i < lineCount; i++) { String line = input.readLine(); int atom1 = Integer.parseInt(line.substring(10, 13).trim()) - 1; int atom2 = Integer.parseInt(line.substring(16, 19).trim()) - 1; if (container.getBond(container.getAtom(atom1), container.getAtom(atom2)) == null) { IBond bond = container.getBuilder().newBond(container.getAtom(atom1), container.getAtom(atom2)); int order = Integer.parseInt(line.substring(23).trim()); bond.setOrder(BondManipulator.createBondOrder((double) order)); container.addBond(bond); } // else: bond already present; CTX store the bonds twice } }
@Test public void testNNMolecule_IAtomContainer() { IAtomContainer acetone = new org.openscience.cdk.AtomContainer(); IAtom c1 = acetone.getBuilder().newAtom("C"); IAtom c2 = acetone.getBuilder().newAtom("C"); IAtom o = acetone.getBuilder().newAtom("O"); IAtom c3 = acetone.getBuilder().newAtom("C"); acetone.addAtom(c1); acetone.addAtom(c2); acetone.addAtom(c3); acetone.addAtom(o); IBond b1 = acetone.getBuilder().newBond(c1, c2, IBond.Order.SINGLE); IBond b2 = acetone.getBuilder().newBond(c1, o, IBond.Order.DOUBLE); IBond b3 = acetone.getBuilder().newBond(c1, c3, IBond.Order.SINGLE); acetone.addBond(b1); acetone.addBond(b2); acetone.addBond(b3); IMolecule m = new NNMolecule(acetone); Assert.assertNotNull(m); Assert.assertEquals(4, m.getAtomCount()); Assert.assertEquals(3, m.getBondCount()); }
/** * Method that actually does the work of convert the atomContainer to IMolecularFormula given a * IMolecularFormula. * * <p>The hydrogens must be implicit. * * @param atomContainer IAtomContainer object * @param formula IMolecularFormula molecularFormula to put the new Isotopes * @return the filled AtomContainer * @see #getMolecularFormula(IAtomContainer) */ public static IMolecularFormula getMolecularFormula( IAtomContainer atomContainer, IMolecularFormula formula) { int charge = 0; IAtom hAtom = null; for (IAtom iAtom : atomContainer.atoms()) { formula.addIsotope(iAtom); if (iAtom.getFormalCharge() != null) charge += iAtom.getFormalCharge(); if (iAtom.getImplicitHydrogenCount() != null && (iAtom.getImplicitHydrogenCount() > 0)) { if (hAtom == null) hAtom = atomContainer.getBuilder().newInstance(IAtom.class, "H"); formula.addIsotope(hAtom, iAtom.getImplicitHydrogenCount()); } } formula.setCharge(charge); return formula; }
/** * Helper method to generate 2d coordinates when JChempaint loads a molecule * without 2D coordinates. Typically happens for SMILES strings. * * @param molecules * @throws Exception */ private static void generate2dCoordinates( final List<IAtomContainer> molecules) { final StructureDiagramGenerator sdg = new StructureDiagramGenerator(); for (int atIdx = 0; atIdx < molecules.size(); atIdx++) { final IAtomContainer mol = molecules.get(atIdx); sdg.setMolecule(mol.getBuilder().newInstance(IAtomContainer.class, mol)); try { sdg.generateCoordinates(); } catch (final Exception e) { e.printStackTrace(); } final IAtomContainer ac = sdg.getMolecule(); for (int i = 0; i < ac.getAtomCount(); i++) { mol.getAtom(i).setPoint2d(ac.getAtom(i).getPoint2d()); } } }
/** * Returns the number of double bond equivalents in this molecule. * * @param formula The IMolecularFormula to calculate * @return The number of DBEs * @throws CDKException if DBE cannot be be evaluated * @cdk.keyword DBE * @cdk.keyword double bond equivalent */ public static double getDBE(IMolecularFormula formula) throws CDKException { int valencies[] = new int[5]; IAtomContainer ac = getAtomContainer(formula); AtomTypeFactory factory = AtomTypeFactory.getInstance( "org/openscience/cdk/config/data/structgen_atomtypes.xml", ac.getBuilder()); for (int f = 0; f < ac.getAtomCount(); f++) { IAtomType[] types = factory.getAtomTypes(ac.getAtom(f).getSymbol()); if (types.length == 0) throw new CDKException( "Calculation of double bond equivalents not possible due to problems with element " + ac.getAtom(f).getSymbol()); // valencies[(int) (types[0].getBondOrderSum() + ac.getAtom(f).getFormalCharge())]++; valencies[types[0].getBondOrderSum().intValue()]++; } return 1 + (valencies[4]) + (valencies[3] / 2) - (valencies[1] / 2); }
/** * Convert the input into a pcore molecule. * * @param input the compound being converted from * @return pcore molecule * @throws CDKException match failed */ private IAtomContainer getPharmacophoreMolecule(IAtomContainer input) throws CDKException { // XXX: prepare query, to be moved prepareInput(input); IAtomContainer pharmacophoreMolecule = input.getBuilder().newInstance(IAtomContainer.class, 0, 0, 0, 0); final Set<String> matched = new HashSet<>(); final Set<PharmacophoreAtom> uniqueAtoms = new LinkedHashSet<>(); logger.debug("Converting [" + input.getProperty(CDKConstants.TITLE) + "] to a pcore molecule"); // lets loop over each pcore query atom for (IAtom atom : pharmacophoreQuery.atoms()) { final PharmacophoreQueryAtom qatom = (PharmacophoreQueryAtom) atom; final String smarts = qatom.getSmarts(); // a pcore query might have multiple instances of a given pcore atom (say // 2 hydrophobic groups separated by X unit). In such a case we want to find // the atoms matching the pgroup SMARTS just once, rather than redoing the // matching for each instance of the pcore query atom. if (!matched.add(qatom.getSymbol())) continue; // see if the smarts for this pcore query atom gets any matches // in our query molecule. If so, then collect each set of // matching atoms and for each set make a new pcore atom and // add it to the pcore atom container object int count = 0; for (final IQueryAtomContainer query : qatom.getCompiledSmarts()) { // create the lazy mappings iterator final Mappings mappings = Pattern.findSubstructure(query).matchAll(input).uniqueAtoms(); for (final int[] mapping : mappings) { uniqueAtoms.add(newPCoreAtom(input, qatom, smarts, mapping)); count++; } } logger.debug("\tFound " + count + " unique matches for " + smarts); } pharmacophoreMolecule.setAtoms(uniqueAtoms.toArray(new IAtom[uniqueAtoms.size()])); // now that we have added all the pcore atoms to the container // we need to join all atoms with pcore bonds (i.e. distance constraints) if (hasDistanceConstraints(pharmacophoreQuery)) { int npatom = pharmacophoreMolecule.getAtomCount(); for (int i = 0; i < npatom - 1; i++) { for (int j = i + 1; j < npatom; j++) { PharmacophoreAtom atom1 = (PharmacophoreAtom) pharmacophoreMolecule.getAtom(i); PharmacophoreAtom atom2 = (PharmacophoreAtom) pharmacophoreMolecule.getAtom(j); PharmacophoreBond bond = new PharmacophoreBond(atom1, atom2); pharmacophoreMolecule.addBond(bond); } } } // if we have angle constraints, generate only the valid // possible angle relationships, rather than all possible if (hasAngleConstraints(pharmacophoreQuery)) { int nangleDefs = 0; for (IBond bond : pharmacophoreQuery.bonds()) { if (!(bond instanceof PharmacophoreQueryAngleBond)) continue; IAtom startQAtom = bond.getAtom(0); IAtom middleQAtom = bond.getAtom(1); IAtom endQAtom = bond.getAtom(2); // make a list of the patoms in the target that match // each type of angle atom List<IAtom> startl = new ArrayList<IAtom>(); List<IAtom> middlel = new ArrayList<IAtom>(); List<IAtom> endl = new ArrayList<IAtom>(); for (IAtom tatom : pharmacophoreMolecule.atoms()) { if (tatom.getSymbol().equals(startQAtom.getSymbol())) startl.add(tatom); if (tatom.getSymbol().equals(middleQAtom.getSymbol())) middlel.add(tatom); if (tatom.getSymbol().equals(endQAtom.getSymbol())) endl.add(tatom); } // now we form the relevant angles, but we will // have reversed repeats List<IAtom[]> tmpl = new ArrayList<IAtom[]>(); for (IAtom middle : middlel) { for (IAtom start : startl) { if (middle.equals(start)) continue; for (IAtom end : endl) { if (start.equals(end) || middle.equals(end)) continue; tmpl.add(new IAtom[] {start, middle, end}); } } } // now clean up reversed repeats List<IAtom[]> unique = new ArrayList<IAtom[]>(); for (int i = 0; i < tmpl.size(); i++) { IAtom[] seq1 = tmpl.get(i); boolean isRepeat = false; for (int j = 0; j < unique.size(); j++) { if (i == j) continue; IAtom[] seq2 = unique.get(j); if (seq1[1] == seq2[1] && seq1[0] == seq2[2] && seq1[2] == seq2[0]) { isRepeat = true; } } if (!isRepeat) unique.add(seq1); } // finally we can add the unique angle to the target for (IAtom[] seq : unique) { PharmacophoreAngleBond pbond = new PharmacophoreAngleBond( (PharmacophoreAtom) seq[0], (PharmacophoreAtom) seq[1], (PharmacophoreAtom) seq[2]); pharmacophoreMolecule.addBond(pbond); nangleDefs++; } } logger.debug("Added " + nangleDefs + " defs to the target pcore molecule"); } return pharmacophoreMolecule; }
/** * Method that actually does the work of convert the atomContainer to IMolecularFormula. * * <p>The hydrogens must be implicit. * * @param atomContainer IAtomContainer object * @return a molecular formula object * @see #getMolecularFormula(IAtomContainer,IMolecularFormula) */ public static IMolecularFormula getMolecularFormula(IAtomContainer atomContainer) { IMolecularFormula formula = atomContainer.getBuilder().newInstance(IMolecularFormula.class); return getMolecularFormula(atomContainer, formula); }
/** * Initiate process. It is needed to call the addExplicitHydrogensToSatisfyValency from the class * tools.HydrogenAdder. * * @exception CDKException Description of the Exception * @param reactants reactants of the reaction. * @param agents agents of the reaction (Must be in this case null). */ @TestMethod("testInitiate_IAtomContainerSet_IAtomContainerSet") public IReactionSet initiate(IAtomContainerSet reactants, IAtomContainerSet agents) throws CDKException { logger.debug("initiate reaction: RearrangementRadicalReaction"); if (reactants.getAtomContainerCount() != 1) { throw new CDKException("RearrangementRadicalReaction only expects one reactant"); } if (agents != null) { throw new CDKException("RearrangementRadicalReaction don't expects agents"); } IReactionSet setOfReactions = DefaultChemObjectBuilder.getInstance().newInstance(IReactionSet.class); IAtomContainer reactant = reactants.getAtomContainer(0); /* if the parameter hasActiveCenter is not fixed yet, set the active centers*/ IParameterReact ipr = super.getParameterClass(SetReactionCenter.class); if (ipr != null && !ipr.isSetParameter()) setActiveCenters(reactant); Iterator<IAtom> atoms = reactants.getAtomContainer(0).atoms().iterator(); while (atoms.hasNext()) { IAtom atomi = atoms.next(); if (atomi.getFlag(CDKConstants.REACTIVE_CENTER) && reactant.getConnectedSingleElectronsCount(atomi) == 1) { Iterator<IBond> bondis = reactant.getConnectedBondsList(atomi).iterator(); while (bondis.hasNext()) { IBond bondi = bondis.next(); if (bondi.getFlag(CDKConstants.REACTIVE_CENTER) && bondi.getOrder() == IBond.Order.SINGLE) { IAtom atomj = bondi.getConnectedAtom(atomi); if (atomi.getFlag(CDKConstants.REACTIVE_CENTER) && (atomj.getFormalCharge() == CDKConstants.UNSET ? 0 : atomj.getFormalCharge()) == 0 && reactant.getConnectedSingleElectronsCount(atomj) == 0) { Iterator<IBond> bondjs = reactant.getConnectedBondsList(atomj).iterator(); while (bondjs.hasNext()) { IBond bondj = bondjs.next(); if (bondj.equals(bondi)) continue; if (bondj.getFlag(CDKConstants.REACTIVE_CENTER) && bondj.getOrder() == IBond.Order.DOUBLE) { IAtom atomk = bondj.getConnectedAtom(atomj); if (atomk.getFlag(CDKConstants.REACTIVE_CENTER) && (atomk.getFormalCharge() == CDKConstants.UNSET ? 0 : atomk.getFormalCharge()) == 0 && reactant.getConnectedSingleElectronsCount(atomk) == 0) { ArrayList<IAtom> atomList = new ArrayList<IAtom>(); atomList.add(atomi); atomList.add(atomj); atomList.add(atomk); ArrayList<IBond> bondList = new ArrayList<IBond>(); bondList.add(bondi); bondList.add(bondj); IAtomContainerSet moleculeSet = reactant.getBuilder().newInstance(IAtomContainerSet.class); moleculeSet.addAtomContainer(reactant); IReaction reaction = mechanism.initiate(moleculeSet, atomList, bondList); if (reaction == null) continue; else setOfReactions.addReaction(reaction); } } } } } } } } return setOfReactions; }
private static IAtomContainer change( IAtomContainer ac, int x1, int y1, int x2, int y2, double b11, double b12, double b21, double b22) { IAtom ax1 = null, ax2 = null, ay1 = null, ay2 = null; IBond b1 = null, b2 = null, b3 = null, b4 = null; try { ax1 = ac.getAtom(x1); ax2 = ac.getAtom(x2); ay1 = ac.getAtom(y1); ay2 = ac.getAtom(y2); } catch (Exception exc) { logger.debug(exc); } b1 = ac.getBond(ax1, ay1); b2 = ac.getBond(ax1, ay2); b3 = ac.getBond(ax2, ay1); b4 = ac.getBond(ax2, ay2); if (b11 > 0) { if (b1 == null) { logger.debug("no bond " + x1 + "-" + y1 + ". Adding it with order " + b11); b1 = ac.getBuilder().newBond(ax1, ay1, BondManipulator.createBondOrder(b11)); ac.addBond(b1); } else { b1.setOrder(BondManipulator.createBondOrder(b11)); logger.debug("Setting bondorder for " + x1 + "-" + y1 + " to " + b11); } } else if (b1 != null) { ac.removeBond(b1); logger.debug("removing bond " + x1 + "-" + y1); } if (b12 > 0) { if (b2 == null) { logger.debug("no bond " + x1 + "-" + y2 + ". Adding it with order " + b12); b2 = ac.getBuilder().newBond(ax1, ay2, BondManipulator.createBondOrder(b12)); ac.addBond(b2); } else { b2.setOrder(BondManipulator.createBondOrder(b12)); logger.debug("Setting bondorder for " + x1 + "-" + y2 + " to " + b12); } } else if (b2 != null) { ac.removeBond(b2); logger.debug("removing bond " + x1 + "-" + y2); } if (b21 > 0) { if (b3 == null) { logger.debug("no bond " + x2 + "-" + y1 + ". Adding it with order " + b21); b3 = ac.getBuilder().newBond(ax2, ay1, BondManipulator.createBondOrder(b21)); ac.addBond(b3); } else { b3.setOrder(BondManipulator.createBondOrder(b21)); logger.debug("Setting bondorder for " + x2 + "-" + y1 + " to " + b21); } } else if (b3 != null) { ac.removeBond(b3); logger.debug("removing bond " + x2 + "-" + y1); } if (b22 > 0) { if (b4 == null) { logger.debug("no bond " + x2 + "-" + y2 + ". Adding it with order " + b22); b4 = ac.getBuilder().newBond(ax2, ay2, BondManipulator.createBondOrder(b22)); ac.addBond(b4); } else { b4.setOrder(BondManipulator.createBondOrder(b22)); logger.debug("Setting bondorder for " + x2 + "-" + y2 + " to " + b22); } } else if (b4 != null) { ac.removeBond(b4); logger.debug("removing bond " + x2 + "-" + y2); } return ac; }
/** * Read an IAtomContainer from a file in MDL sd format * * @return The Molecule that was read from the MDL file. */ private IAtomContainer readAtomContainer(IAtomContainer molecule) throws CDKException { logger.debug("Reading new molecule"); IAtomContainer outputContainer = null; int linecount = 0; int atoms = 0; int bonds = 0; int atom1 = 0; int atom2 = 0; int order = 0; IBond.Stereo stereo = (IBond.Stereo) CDKConstants.UNSET; int RGroupCounter = 1; int Rnumber = 0; String[] rGroup = null; double x = 0.0; double y = 0.0; double z = 0.0; double totalX = 0.0; double totalY = 0.0; double totalZ = 0.0; String title = null; String remark = null; // int[][] conMat = new int[0][0]; // String help; IAtom atom; String line = ""; // A map to keep track of R# atoms so that RGP line can be parsed Map<Integer, IPseudoAtom> rAtoms = new HashMap<Integer, IPseudoAtom>(); try { IsotopeFactory isotopeFactory = Isotopes.getInstance(); logger.info("Reading header"); line = input.readLine(); linecount++; if (line == null) { return null; } logger.debug("Line " + linecount + ": " + line); if (line.startsWith("$$$$")) { logger.debug("File is empty, returning empty molecule"); return molecule; } if (line.length() > 0) { title = line; } line = input.readLine(); linecount++; logger.debug("Line " + linecount + ": " + line); line = input.readLine(); linecount++; logger.debug("Line " + linecount + ": " + line); if (line.length() > 0) { remark = line; } logger.info("Reading rest of file"); line = input.readLine(); linecount++; logger.debug("Line " + linecount + ": " + line); // if the line is empty we hav a problem - either a malformed // molecule entry or just extra new lines at the end of the file if (line.length() == 0) { // read till the next $$$$ or EOF while (true) { line = input.readLine(); linecount++; if (line == null) { return null; } if (line.startsWith("$$$$")) { return molecule; // an empty molecule } } } // check the CT block version if (line.contains("V3000") || line.contains("v3000")) { handleError("This file must be read with the MDLV3000Reader."); } else if (!line.contains("V2000") && !line.contains("v2000")) { handleError("This file must be read with the MDLReader."); } atoms = Integer.parseInt(line.substring(0, 3).trim()); List<IAtom> atomList = new ArrayList<IAtom>(); logger.debug("Atomcount: " + atoms); bonds = Integer.parseInt(line.substring(3, 6).trim()); logger.debug("Bondcount: " + bonds); List<IBond> bondList = new ArrayList<IBond>(); // used for applying the MDL valence model int[] explicitValence = new int[atoms]; // read ATOM block logger.info("Reading atom block"); atomsByLinePosition = new ArrayList<IAtom>(); atomsByLinePosition.add(null); // 0 is not a valid position int atomBlockLineNumber = 0; for (int f = 0; f < atoms; f++) { line = input.readLine(); linecount++; atomBlockLineNumber++; Matcher trailingSpaceMatcher = TRAILING_SPACE.matcher(line); if (trailingSpaceMatcher.find()) { handleError( "Trailing space found", linecount, trailingSpaceMatcher.start(), trailingSpaceMatcher.end()); line = trailingSpaceMatcher.replaceAll(""); } x = Double.parseDouble(line.substring(0, 10).trim()); y = Double.parseDouble(line.substring(10, 20).trim()); z = Double.parseDouble(line.substring(20, 30).trim()); // *all* values should be zero, not just the sum totalX += Math.abs(x); totalY += Math.abs(y); totalZ += Math.abs(z); logger.debug("Coordinates: " + x + "; " + y + "; " + z); String element = line.substring(31, Math.min(line.length(), 34)).trim(); if (line.length() < 34) { handleError( "Element atom type does not follow V2000 format type should of length three" + " and padded with space if required", linecount, 31, 34); } logger.debug("Atom type: ", element); if (isotopeFactory.isElement(element)) { atom = isotopeFactory.configure(molecule.getBuilder().newInstance(IAtom.class, element)); } else if ("A".equals(element)) { atom = molecule.getBuilder().newInstance(IPseudoAtom.class, element); } else if ("Q".equals(element)) { atom = molecule.getBuilder().newInstance(IPseudoAtom.class, element); } else if ("*".equals(element)) { atom = molecule.getBuilder().newInstance(IPseudoAtom.class, element); } else if ("LP".equals(element)) { atom = molecule.getBuilder().newInstance(IPseudoAtom.class, element); } else if ("L".equals(element)) { atom = molecule.getBuilder().newInstance(IPseudoAtom.class, element); } else if (element.equals("R") || (element.length() > 0 && element.charAt(0) == 'R')) { logger.debug("Atom ", element, " is not an regular element. Creating a PseudoAtom."); // check if the element is R rGroup = element.split("^R"); atom = null; if (rGroup.length > 1) { try { Rnumber = Integer.valueOf(rGroup[(rGroup.length - 1)]); RGroupCounter = Rnumber; element = "R" + Rnumber; atom = molecule.getBuilder().newInstance(IPseudoAtom.class, element); } catch (Exception ex) { // This happens for atoms labeled "R#". // The Rnumber may be set later on, using RGP line atom = molecule.getBuilder().newInstance(IPseudoAtom.class, "R"); rAtoms.put(atomBlockLineNumber, (IPseudoAtom) atom); } } else { atom = molecule.getBuilder().newInstance(IPseudoAtom.class, element); } } else { handleError( "Invalid element type. Must be an existing " + "element, or one in: A, Q, L, LP, *.", linecount, 32, 35); atom = molecule.getBuilder().newInstance(IPseudoAtom.class, element); atom.setSymbol(element); } // store as 3D for now, convert to 2D (if totalZ == 0.0) later atom.setPoint3d(new Point3d(x, y, z)); // parse further fields if (line.length() >= 36) { String massDiffString = line.substring(34, 36).trim(); logger.debug("Mass difference: ", massDiffString); if (!(atom instanceof IPseudoAtom)) { try { int massDiff = Integer.parseInt(massDiffString); if (massDiff != 0) { IIsotope major = Isotopes.getInstance().getMajorIsotope(element); atom.setMassNumber(major.getMassNumber() + massDiff); } } catch (Exception exception) { handleError("Could not parse mass difference field.", linecount, 35, 37, exception); } } else { logger.error("Cannot set mass difference for a non-element!"); } } else { handleError("Mass difference is missing", linecount, 34, 36); } // set the stereo partiy Integer parity = line.length() > 41 ? Character.digit(line.charAt(41), 10) : 0; atom.setStereoParity(parity); if (line.length() >= 51) { String valenceString = removeNonDigits(line.substring(48, 51)); logger.debug("Valence: ", valenceString); if (!(atom instanceof IPseudoAtom)) { try { int valence = Integer.parseInt(valenceString); if (valence != 0) { // 15 is defined as 0 in mol files if (valence == 15) atom.setValency(0); else atom.setValency(valence); } } catch (Exception exception) { handleError( "Could not parse valence information field", linecount, 49, 52, exception); } } else { logger.error("Cannot set valence information for a non-element!"); } } if (line.length() >= 39) { String chargeCodeString = line.substring(36, 39).trim(); logger.debug("Atom charge code: ", chargeCodeString); int chargeCode = Integer.parseInt(chargeCodeString); if (chargeCode == 0) { // uncharged species } else if (chargeCode == 1) { atom.setFormalCharge(+3); } else if (chargeCode == 2) { atom.setFormalCharge(+2); } else if (chargeCode == 3) { atom.setFormalCharge(+1); } else if (chargeCode == 4) { } else if (chargeCode == 5) { atom.setFormalCharge(-1); } else if (chargeCode == 6) { atom.setFormalCharge(-2); } else if (chargeCode == 7) { atom.setFormalCharge(-3); } } else { handleError("Atom charge is missing", linecount, 36, 39); } try { // read the mmm field as position 61-63 String reactionAtomIDString = line.substring(60, 63).trim(); logger.debug("Parsing mapping id: ", reactionAtomIDString); try { int reactionAtomID = Integer.parseInt(reactionAtomIDString); if (reactionAtomID != 0) { atom.setProperty(CDKConstants.ATOM_ATOM_MAPPING, reactionAtomID); } } catch (Exception exception) { logger.error("Mapping number ", reactionAtomIDString, " is not an integer."); logger.debug(exception); } } catch (Exception exception) { // older mol files don't have all these fields... logger.warn("A few fields are missing. Older MDL MOL file?"); } // shk3: This reads shifts from after the molecule. I don't think this is an official // format, but I saw it frequently 80=>78 for alk if (line.length() >= 78) { double shift = Double.parseDouble(line.substring(69, 80).trim()); atom.setProperty("first shift", shift); } if (line.length() >= 87) { double shift = Double.parseDouble(line.substring(79, 87).trim()); atom.setProperty("second shift", shift); } atomList.add(atom); atomsByLinePosition.add(atom); } // convert to 2D, if totalZ == 0 if (totalX == 0.0 && totalY == 0.0 && totalZ == 0.0) { logger.info("All coordinates are 0.0"); if (atomList.size() == 1) { atomList.get(0).setPoint2d(new Point2d(x, y)); } else { for (IAtom atomToUpdate : atomList) { atomToUpdate.setPoint3d(null); } } } else if (totalZ == 0.0 && !forceReadAs3DCoords.isSet()) { logger.info("Total 3D Z is 0.0, interpreting it as a 2D structure"); for (IAtom atomToUpdate : atomList) { Point3d p3d = atomToUpdate.getPoint3d(); if (p3d != null) { atomToUpdate.setPoint2d(new Point2d(p3d.x, p3d.y)); atomToUpdate.setPoint3d(null); } } } // read BOND block logger.info("Reading bond block"); int queryBondCount = 0; for (int f = 0; f < bonds; f++) { line = input.readLine(); linecount++; atom1 = Integer.parseInt(line.substring(0, 3).trim()); atom2 = Integer.parseInt(line.substring(3, 6).trim()); order = Integer.parseInt(line.substring(6, 9).trim()); if (line.length() >= 12) { int mdlStereo = line.length() > 12 ? Integer.parseInt(line.substring(9, 12).trim()) : Integer.parseInt(line.substring(9).trim()); if (mdlStereo == 1) { // MDL up bond stereo = IBond.Stereo.UP; } else if (mdlStereo == 6) { // MDL down bond stereo = IBond.Stereo.DOWN; } else if (mdlStereo == 0) { if (order == 2) { // double bond stereo defined by coordinates stereo = IBond.Stereo.E_Z_BY_COORDINATES; } else { // bond has no stereochemistry stereo = IBond.Stereo.NONE; } } else if (mdlStereo == 3 && order == 2) { // unknown E/Z stereochemistry stereo = IBond.Stereo.E_OR_Z; } else if (mdlStereo == 4) { // MDL bond undefined stereo = IBond.Stereo.UP_OR_DOWN; } } else { handleError("Missing expected stereo field at line: ", linecount, 10, 12); } if (logger.isDebugEnabled()) { logger.debug("Bond: " + atom1 + " - " + atom2 + "; order " + order); } // interpret CTfile's special bond orders IAtom a1 = atomList.get(atom1 - 1); IAtom a2 = atomList.get(atom2 - 1); IBond newBond = null; if (order >= 1 && order <= 3) { IBond.Order cdkOrder = IBond.Order.SINGLE; if (order == 2) cdkOrder = IBond.Order.DOUBLE; if (order == 3) cdkOrder = IBond.Order.TRIPLE; if (stereo != null) { newBond = molecule.getBuilder().newInstance(IBond.class, a1, a2, cdkOrder, stereo); } else { newBond = molecule.getBuilder().newInstance(IBond.class, a1, a2, cdkOrder); } } else if (order == 4) { // aromatic bond if (stereo != null) { newBond = molecule.getBuilder().newInstance(IBond.class, a1, a2, IBond.Order.UNSET, stereo); } else { newBond = molecule.getBuilder().newInstance(IBond.class, a1, a2, IBond.Order.UNSET); } // mark both atoms and the bond as aromatic and raise the SINGLE_OR_DOUBLE-flag newBond.setFlag(CDKConstants.SINGLE_OR_DOUBLE, true); newBond.setFlag(CDKConstants.ISAROMATIC, true); a1.setFlag(CDKConstants.ISAROMATIC, true); a2.setFlag(CDKConstants.ISAROMATIC, true); } else { queryBondCount++; newBond = new CTFileQueryBond(molecule.getBuilder()); IAtom[] bondAtoms = {a1, a2}; newBond.setAtoms(bondAtoms); newBond.setOrder(null); CTFileQueryBond.Type queryBondType = null; switch (order) { case 5: queryBondType = CTFileQueryBond.Type.SINGLE_OR_DOUBLE; break; case 6: queryBondType = CTFileQueryBond.Type.SINGLE_OR_AROMATIC; break; case 7: queryBondType = CTFileQueryBond.Type.DOUBLE_OR_AROMATIC; break; case 8: queryBondType = CTFileQueryBond.Type.ANY; break; } ((CTFileQueryBond) newBond).setType(queryBondType); newBond.setStereo(stereo); } bondList.add((newBond)); // add the bond order to the explicit valence for each atom if (newBond.getOrder() != null && newBond.getOrder() != IBond.Order.UNSET) { explicitValence[atom1 - 1] += newBond.getOrder().numeric(); explicitValence[atom2 - 1] += newBond.getOrder().numeric(); } else { explicitValence[atom1 - 1] = Integer.MIN_VALUE; explicitValence[atom2 - 1] = Integer.MIN_VALUE; } } if (queryBondCount == 0) outputContainer = molecule; else { outputContainer = new QueryAtomContainer(molecule.getBuilder()); } outputContainer.setProperty(CDKConstants.TITLE, title); outputContainer.setProperty(CDKConstants.REMARK, remark); for (IAtom at : atomList) { outputContainer.addAtom(at); } for (IBond bnd : bondList) { outputContainer.addBond(bnd); } // read PROPERTY block logger.info("Reading property block"); while (true) { line = input.readLine(); linecount++; if (line == null) { handleError("The expected property block is missing!", linecount, 0, 0); } if (line.startsWith("M END")) break; boolean lineRead = false; if (line.startsWith("M CHG")) { // FIXME: if this is encountered for the first time, all // atom charges should be set to zero first! int infoCount = Integer.parseInt(line.substring(6, 9).trim()); StringTokenizer st = new StringTokenizer(line.substring(9)); for (int i = 1; i <= infoCount; i++) { String token = st.nextToken(); int atomNumber = Integer.parseInt(token.trim()); token = st.nextToken(); int charge = Integer.parseInt(token.trim()); outputContainer.getAtom(atomNumber - 1).setFormalCharge(charge); } } else if (line.matches("A\\s{1,4}\\d+")) { // Reads the pseudo atom property from the mol file // The atom number of the to replaced atom int aliasAtomNumber = Integer.parseInt(line.replaceFirst("A\\s{1,4}", "")) - RGroupCounter; line = input.readLine(); linecount++; String[] aliasArray = line.split("\\\\"); // name of the alias atom like R1 or R2 etc. String alias = ""; for (int i = 0; i < aliasArray.length; i++) { alias += aliasArray[i]; } IAtom aliasAtom = outputContainer.getAtom(aliasAtomNumber); // skip if already a pseudoatom if (aliasAtom instanceof IPseudoAtom) { ((IPseudoAtom) aliasAtom).setLabel(alias); continue; } IAtom newPseudoAtom = molecule.getBuilder().newInstance(IPseudoAtom.class, alias); if (aliasAtom.getPoint2d() != null) { newPseudoAtom.setPoint2d(aliasAtom.getPoint2d()); } if (aliasAtom.getPoint3d() != null) { newPseudoAtom.setPoint3d(aliasAtom.getPoint3d()); } outputContainer.addAtom(newPseudoAtom); List<IBond> bondsOfAliasAtom = outputContainer.getConnectedBondsList(aliasAtom); for (int i = 0; i < bondsOfAliasAtom.size(); i++) { IBond bondOfAliasAtom = bondsOfAliasAtom.get(i); IAtom connectedToAliasAtom = bondOfAliasAtom.getConnectedAtom(aliasAtom); IBond newBond = bondOfAliasAtom.getBuilder().newInstance(IBond.class); newBond.setAtoms(new IAtom[] {connectedToAliasAtom, newPseudoAtom}); newBond.setOrder(bondOfAliasAtom.getOrder()); outputContainer.addBond(newBond); outputContainer.removeBond(aliasAtom, connectedToAliasAtom); } outputContainer.removeAtom(aliasAtom); RGroupCounter++; } else if (line.startsWith("M ISO")) { try { String countString = line.substring(6, 10).trim(); int infoCount = Integer.parseInt(countString); StringTokenizer st = new StringTokenizer(line.substring(10)); for (int i = 1; i <= infoCount; i++) { int atomNumber = Integer.parseInt(st.nextToken().trim()); int absMass = Integer.parseInt(st.nextToken().trim()); if (absMass != 0) { IAtom isotope = outputContainer.getAtom(atomNumber - 1); isotope.setMassNumber(absMass); } } } catch (NumberFormatException exception) { String error = "Error (" + exception.getMessage() + ") while parsing line " + linecount + ": " + line + " in property block."; logger.error(error); handleError( "NumberFormatException in isotope information.", linecount, 7, 11, exception); } } else if (line.startsWith("M RAD")) { try { String countString = line.substring(6, 9).trim(); int infoCount = Integer.parseInt(countString); StringTokenizer st = new StringTokenizer(line.substring(9)); for (int i = 1; i <= infoCount; i++) { int atomNumber = Integer.parseInt(st.nextToken().trim()); int spinMultiplicity = Integer.parseInt(st.nextToken().trim()); MDLV2000Writer.SPIN_MULTIPLICITY spin = MDLV2000Writer.SPIN_MULTIPLICITY.NONE; if (spinMultiplicity > 0) { IAtom radical = outputContainer.getAtom(atomNumber - 1); switch (spinMultiplicity) { case 1: spin = MDLV2000Writer.SPIN_MULTIPLICITY.DOUBLET; break; case 2: spin = MDLV2000Writer.SPIN_MULTIPLICITY.SINGLET; break; case 3: spin = MDLV2000Writer.SPIN_MULTIPLICITY.TRIPLET; break; default: logger.debug("Invalid spin multiplicity found: " + spinMultiplicity); break; } for (int j = 0; j < spin.getSingleElectrons(); j++) { outputContainer.addSingleElectron( molecule.getBuilder().newInstance(ISingleElectron.class, radical)); } } } } catch (NumberFormatException exception) { String error = "Error (" + exception.getMessage() + ") while parsing line " + linecount + ": " + line + " in property block."; logger.error(error); handleError( "NumberFormatException in radical information", linecount, 7, 10, exception); } } else if (line.startsWith("G ")) { try { String atomNumberString = line.substring(3, 6).trim(); int atomNumber = Integer.parseInt(atomNumberString); // String whatIsThisString = line.substring(6,9).trim(); String atomName = input.readLine(); // convert Atom into a PseudoAtom IAtom prevAtom = outputContainer.getAtom(atomNumber - 1); IPseudoAtom pseudoAtom = molecule.getBuilder().newInstance(IPseudoAtom.class, atomName); if (prevAtom.getPoint2d() != null) { pseudoAtom.setPoint2d(prevAtom.getPoint2d()); } if (prevAtom.getPoint3d() != null) { pseudoAtom.setPoint3d(prevAtom.getPoint3d()); } AtomContainerManipulator.replaceAtomByAtom(molecule, prevAtom, pseudoAtom); } catch (NumberFormatException exception) { String error = "Error (" + exception.toString() + ") while parsing line " + linecount + ": " + line + " in property block."; logger.error(error); handleError("NumberFormatException in group information", linecount, 4, 7, exception); } } else if (line.startsWith("M RGP")) { StringTokenizer st = new StringTokenizer(line); // Ignore first 3 tokens (overhead). st.nextToken(); st.nextToken(); st.nextToken(); // Process the R group numbers as defined in RGP line. while (st.hasMoreTokens()) { Integer position = new Integer(st.nextToken()); Rnumber = new Integer(st.nextToken()); IPseudoAtom pseudoAtom = rAtoms.get(position); if (pseudoAtom != null) { pseudoAtom.setLabel("R" + Rnumber); } } } if (line.startsWith("V ")) { Integer atomNumber = new Integer(line.substring(3, 6).trim()); IAtom atomWithComment = outputContainer.getAtom(atomNumber - 1); atomWithComment.setProperty(CDKConstants.COMMENT, line.substring(7)); } if (!lineRead) { logger.warn("Skipping line in property block: ", line); } } if (interpretHydrogenIsotopes.isSet()) { fixHydrogenIsotopes(molecule, isotopeFactory); } // note: apply the valence model last so that all fixes (i.e. hydrogen // isotopes) are in place for (int i = 0; i < atoms; i++) { applyMDLValenceModel(outputContainer.getAtom(i), explicitValence[i]); } } catch (CDKException exception) { String error = "Error while parsing line " + linecount + ": " + line + " -> " + exception.getMessage(); logger.error(error); logger.debug(exception); throw exception; } catch (Exception exception) { exception.printStackTrace(); String error = "Error while parsing line " + linecount + ": " + line + " -> " + exception.getMessage(); logger.error(error); logger.debug(exception); handleError("Error while parsing line: " + line, linecount, 0, 0, exception); } return outputContainer; }
public String perceiveSybylAtomTypes(IMolecule mol) throws InvocationTargetException { ICDKMolecule cdkmol; try { cdkmol = cdk.asCDKMolecule(mol); } catch (BioclipseException e) { System.out.println("Error converting cdk10 to cdk"); e.printStackTrace(); throw new InvocationTargetException(e); } IAtomContainer ac = cdkmol.getAtomContainer(); CDKAtomTypeMatcher cdkMatcher = CDKAtomTypeMatcher.getInstance(ac.getBuilder()); AtomTypeMapper mapper = AtomTypeMapper.getInstance( "org/openscience/cdk/dict/data/cdk-sybyl-mappings.owl" ); IAtomType[] sybylTypes = new IAtomType[ac.getAtomCount()]; int atomCounter = 0; int a=0; for (IAtom atom : ac.atoms()) { IAtomType type; try { type = cdkMatcher.findMatchingAtomType(ac, atom); } catch (CDKException e) { type = null; } if (type==null) { // logger.debug("AT null for atom: " + atom); type = atom.getBuilder().newAtomType(atom.getSymbol()); type.setAtomTypeName("X"); } AtomTypeManipulator.configure(atom, type); a++; } try { CDKHueckelAromaticityDetector.detectAromaticity(ac); // System.out.println("Arom: " // + CDKHueckelAromaticityDetector.detectAromaticity(ac) ); } catch (CDKException e) { logger.debug("Failed to perceive aromaticity: " + e.getMessage()); } for (IAtom atom : ac.atoms()) { String mappedType = mapper.mapAtomType(atom.getAtomTypeName()); if ("C.2".equals(mappedType) && atom.getFlag(CDKConstants.ISAROMATIC)) { mappedType = "C.ar"; } else if ("N.pl3".equals(mappedType) && atom.getFlag(CDKConstants.ISAROMATIC)) { mappedType = "N.ar"; } try { sybylTypes[atomCounter] = factory.getAtomType(mappedType); } catch (NoSuchAtomTypeException e) { // yes, setting null's here is important sybylTypes[atomCounter] = null; } atomCounter++; } StringBuffer result = new StringBuffer(); // now that full perception is finished, we can set atom type names: for (int i = 0; i < sybylTypes.length; i++) { if (sybylTypes[i] != null) { ac.getAtom(i).setAtomTypeName(sybylTypes[i].getAtomTypeName()); } else { ac.getAtom(i).setAtomTypeName("X"); } result.append(i).append(':').append(ac.getAtom(i).getAtomTypeName()) /*.append("\n")*/; } return result.toString(); }
/** A unit test for JUnit */ @Test public void testCisResorcinol() throws Exception { HydrogenPlacer hydrogenPlacer = new HydrogenPlacer(); IAtomContainer mol1 = new AtomContainer(); SmilesGenerator sg = new SmilesGenerator(); mol1.addAtom(new Atom("O", new Point2d(3, 1))); // 1 mol1.addAtom(new Atom("H", new Point2d(2, 0))); // 2 mol1.addAtom(new Atom("C", new Point2d(2, 1))); // 3 mol1.addAtom(new Atom("C", new Point2d(1, 1))); // 4 mol1.addAtom(new Atom("C", new Point2d(1, 4))); // 5 mol1.addAtom(new Atom("C", new Point2d(1, 5))); // 6 mol1.addAtom(new Atom("C", new Point2d(1, 2))); // 7 mol1.addAtom(new Atom("C", new Point2d(2, 2))); // 1 mol1.addAtom(new Atom("O", new Point2d(3, 2))); // 2 mol1.addAtom(new Atom("H", new Point2d(2, 3))); // 3 mol1.addBond(0, 2, IBond.Order.SINGLE, IBond.Stereo.DOWN); // 1 mol1.addBond(1, 2, IBond.Order.SINGLE, IBond.Stereo.UP); // 2 mol1.addBond(2, 3, IBond.Order.SINGLE); // 3 mol1.addBond(3, 4, IBond.Order.SINGLE); // 4 mol1.addBond(4, 5, IBond.Order.SINGLE); // 5 mol1.addBond(5, 6, IBond.Order.SINGLE); // 6 mol1.addBond(6, 7, IBond.Order.SINGLE); // 3 mol1.addBond(7, 8, IBond.Order.SINGLE, IBond.Stereo.UP); // 4 mol1.addBond(7, 9, IBond.Order.SINGLE, IBond.Stereo.DOWN); // 5 mol1.addBond(7, 2, IBond.Order.SINGLE); // 6 try { addExplicitHydrogens(mol1); hydrogenPlacer.placeHydrogens2D(mol1, 1.0); IsotopeFactory ifac = IsotopeFactory.getInstance(mol1.getBuilder()); ifac.configureAtoms(mol1); } catch (IOException ex) { } catch (ClassNotFoundException ex) { } String smiles1 = null; if (standAlone) { display(mol1); } try { smiles1 = sg.createSMILES(mol1, true, new boolean[mol1.getBondCount()]); } catch (Exception exc) { System.out.println(exc); if (!standAlone) { Assert.fail(); } } if (standAlone) { System.err.println("SMILES 1: " + smiles1); } Assert.assertNotNull(smiles1); Assert.assertEquals( "[H]O[C@]1(C([H])([H])C([H])([H])C([H])([H])C([H])([H])[C@]1(O[H])([H]))([H])", smiles1); mol1 = AtomContainerManipulator.removeHydrogens(mol1); try { smiles1 = sg.createSMILES(mol1); } catch (Exception exc) { System.out.println(exc); if (!standAlone) { Assert.fail(); } } if (standAlone) { System.err.println("SMILES 1: " + smiles1); } Assert.assertNotNull(smiles1); Assert.assertEquals("OC1CCCCC1(O)", smiles1); }
/** * Process spectra in the following way: Fragment each hit in KEGG starting with the lowest * collision energy If hits were found they are used for the next measurement as input and the * original molecule is not used. * * @param folder the folder * @param file the file */ private void processSpectra(String folder, String file, int treeDepth) { this.scoreMap = new HashMap<Integer, ArrayList<String>>(); if (blackList.contains(file)) { completeLog += "Blacklisted Molecule: " + file; histogramReal += "\n" + file + "\tBLACKLIST\t"; histogram += "\n" + file + "\tBLACKLIST\t"; histogramCompare += "\n" + file + "\tBLACKLIST\t"; return; } double exactMass = spectra.get(0).getExactMass(); // timing long timeStart = System.currentTimeMillis(); HashMap<Double, Vector<String>> realScoreMap = new HashMap<Double, Vector<String>>(); int mode = spectra.get(0).getMode(); // instantiate and read in CID-KEGG.txt String keggIdentifier = spectra.get(0).getKEGG(); completeLog += "\n\n============================================================================"; completeLog += "\nFile: " + spectra.get(0).getTrivialName() + " (KEGG Entry: " + keggIdentifier + ")"; // get candidates from kegg webservice...with with a given mzppm and mzabs Vector<String> candidates = KeggWebservice.KEGGbyMass(exactMass, (mzabs + PPMTool.getPPMDeviation(exactMass, mzppm))); try { GetKEGGIdentifier keggID = new GetKEGGIdentifier(folder + "CID-KEGG/CID-KEGG.txt"); // now find the corresponding KEGG entry if (keggID.existInKEGG(spectra.get(0).getCID())) keggIdentifier = keggID.getKEGGID(spectra.get(0).getCID()); } catch (IOException e) { System.out.println(e.getMessage()); completeLog += "Error! Message: " + e.getMessage(); } // comparison histogram if (keggIdentifier.equals("none")) histogramCompare += "\n" + file + "\t" + keggIdentifier + "\t\t" + exactMass; else histogramCompare += "\n" + file + "\t" + keggIdentifier + "\t" + candidates.size() + "\t" + exactMass; // list of peaks which are contained in the real molecule Vector<Peak> listOfPeaksCorresponding = new Vector<Peak>(); // list of peaks which are not contained in the real molecule Vector<Peak> listOfPeaks = new Vector<Peak>(); // loop over all hits for (int c = 0; c < candidates.size(); c++) { this.foundHits = new Vector<IAtomContainer>(); // get mol file from kegg....remove "cpd:" String candidate = KeggWebservice.KEGGgetMol(candidates.get(c).substring(4), this.keggPath); IAtomContainer molecule = null; try { // write string to disk new File(folder + file + "_Mol").mkdir(); File outFile = new File(folder + file + "_Mol/" + candidates.get(c).substring(4) + ".mol"); FileWriter out = new FileWriter(outFile); out.write(candidate); out.close(); // now fragment the retrieved molecule molecule = Molfile.Read(folder + file + "_Mol/" + candidates.get(c).substring(4) + ".mol"); // now create a new folder to write the .mol files into new File(folder + file).mkdir(); boolean status = new File(folder + file + "/" + candidates.get(c).substring(4)).mkdir(); } catch (IOException e) { completeLog += "Error: " + candidates.get(c).substring(4) + " Message: " + e.getMessage(); } catch (CDKException e) { completeLog += "Error: " + candidates.get(c).substring(4) + " Message: " + e.getMessage(); } try { // add hydrogens CDKAtomTypeMatcher matcher = CDKAtomTypeMatcher.getInstance(molecule.getBuilder()); for (IAtom atom : molecule.atoms()) { IAtomType type = matcher.findMatchingAtomType(molecule, atom); AtomTypeManipulator.configure(atom, type); } CDKHydrogenAdder hAdder = CDKHydrogenAdder.getInstance(molecule.getBuilder()); hAdder.addImplicitHydrogens(molecule); AtomContainerManipulator.convertImplicitToExplicitHydrogens(molecule); } // there is a bug in cdk?? error happens when there is a S or Ti in the molecule catch (IllegalArgumentException e) { completeLog += "Error: " + candidates.get(c).substring(4) + " Message: " + e.getMessage(); // skip it continue; } catch (CDKException e) { completeLog += "Error: " + candidates.get(c).substring(4) + " Message: " + e.getMessage(); // skip it continue; } // get peak list....it is reset if this is not the first run Vector<Peak> peakList = spectra.get(0).getPeakList(); // create a new instance Fragmenter fragmenter = new Fragmenter( (Vector<Peak>) peakList.clone(), mzabs, mzppm, mode, breakAromaticRings, quickRedundancy, false, false); double combinedScore = 0; int combinedHits = 0; int combinedPeakCount = 0; String peaks = ""; combinedPeakCount = peakList.size(); int count = 0; boolean first = true; // loop over the different collision energies for (WrapperSpectrum spectrum : spectra) { List<IAtomContainer> l = null; long start = System.currentTimeMillis(); try { if (first) { try { l = fragmenter.generateFragmentsInMemory(molecule, true, treeDepth); count++; } catch (OutOfMemoryError e) { System.out.println("OUT OF MEMORY ERROR! " + candidates.get(c).substring(4)); completeLog += "Error: " + candidates.get(c).substring(4) + " Message: " + e.getMessage(); continue; } first = false; } else { peakList = spectrum.getPeakList(); combinedPeakCount += peakList.size(); // set the current peak list... fragmenter.setPeakList((Vector<Peak>) peakList.clone()); try { // l = fragmenter.generateFragmentsHierarchical(foundHits, true); System.err.println("REMOVED....no improvement!"); System.exit(1); count++; } catch (OutOfMemoryError e) { System.out.println("OUT OF MEMORY ERROR! " + candidates.get(c).substring(4)); completeLog += "Error: " + candidates.get(c).substring(4) + " Message: " + e.getMessage(); continue; } } long time = System.currentTimeMillis() - start; System.out.println("Benötigte Zeit: " + time); System.out.println("Got " + l.size() + " fragments"); System.out.println("Needed " + fragmenter.getNround() + " calls to generateFragments()"); new File( folder + file + "/" + candidates.get(c).substring(4) + "/" + spectrum.getCollisionEnergy()) .mkdir(); for (int i = 0; i < l.size(); i++) { try { // write fragments to disk FileWriter w = new FileWriter( new File( folder + file + "/" + candidates.get(c).substring(4) + "/" + spectrum.getCollisionEnergy() + "/frag_" + i + ".mol")); MDLWriter mw = new MDLWriter(w); mw.write(new Molecule(l.get(i))); mw.close(); } catch (IOException e) { System.out.println("IOException: " + e.toString()); completeLog += "Error: " + candidates.get(c).substring(4) + " Message: " + e.getMessage(); } catch (Exception e) { System.out.println(e.toString()); completeLog += "Error: " + candidates.get(c).substring(4) + " Message: " + e.getMessage(); } } // Draw molecule and its fragments if (showDiagrams) Render.Draw(molecule, l, "Original Molecule"); if (pdf) { // Create PDF Output l.add(0, molecule); DisplayStructure ds1 = null; // create pdf subfolder new File(folder + file + "/" + candidates.get(c) + "pdf/").mkdir(); ds1 = new WritePDFTable( true, 300, 300, 0.9, 2, false, false, folder + file + "/" + candidates.get(c) + "pdf/"); for (int i = 0; i < l.size(); i++) { // ds = new displayStructure(false, 300, 300, 0.9, false, "PDF", // "/home/basti/WorkspaceJava/TandemMSLookup/fragmenter/Test"); assert ds1 != null; ds1.drawStructure(l.get(i), i); } if (ds1 != null) ds1.close(); } // now read the saved mol files List<IAtomContainer> fragments = Molfile.Readfolder( folder + file + "/" + candidates.get(c).substring(4) + "/" + spectrum.getCollisionEnergy()); List<IAtomContainer> fragmentsList = new ArrayList<IAtomContainer>(); for (int i = 0; i < fragments.size(); i++) { fragmentsList.add(fragments.get(i)); } // get the original peak list again // spectrum = new SpectrumWrapper(folder + file + ".txt"); peakList = (Vector<Peak>) spectrum.getPeakList().clone(); // clean up peak list CleanUpPeakList cList = new CleanUpPeakList(peakList); Vector<Peak> cleanedPeakList = cList.getCleanedPeakList(spectrum.getExactMass()); // now find corresponding fragments to the mass AssignFragmentPeak afp = new AssignFragmentPeak(); afp.setHydrogenTest(hydrogenTest); afp.assignFragmentPeak( fragments, cleanedPeakList, mzabs, mzppm, spectrum.getMode(), false); Vector<PeakMolPair> hits = afp.getHits(); Vector<PeakMolPair> hitsAll = afp.getAllHits(); // add them to the list of already found fragments....they were found in the previous run // with a smaller collission energy for (PeakMolPair peakMolPair : hitsAll) { foundHits.add(peakMolPair.getFragment()); } combinedHits += ((combinedHits + hits.size()) - combinedHits); // Render.Draw(molecule, foundHits, "Found Hits"); // now "real" scoring Scoring score = new Scoring(cleanedPeakList); double currentScore = score.computeScoring(afp.getHitsMZ()); combinedScore += currentScore; // check for last run and create the data for the log file if (count == spectra.size()) { // save score in hashmap...if there are several hits with the same score --> vector of // strings if (realScoreMap.containsKey(combinedScore)) { Vector<String> tempList = realScoreMap.get(combinedScore); tempList.add(candidates.get(c).substring(4)); realScoreMap.put(combinedScore, tempList); } else { Vector<String> temp = new Vector<String>(); temp.add(candidates.get(c).substring(4)); realScoreMap.put(combinedScore, temp); } // save score in hashmap...if there are several hits with the same // amount of identified peaks --> ArrayList if (scoreMap.containsKey(combinedHits)) { ArrayList<String> tempList = scoreMap.get(combinedHits); tempList.add(candidates.get(c).substring(4)); scoreMap.put(combinedHits, tempList); } else { ArrayList<String> temp = new ArrayList<String>(); temp.add(candidates.get(c).substring(4)); scoreMap.put(combinedHits, temp); } } // get all the identified peaks for (int i = 0; i < hits.size(); i++) { peaks += hits.get(i).getPeak().getMass() + " "; listOfPeaks.add(hits.get(i).getPeak()); if (keggIdentifier.equals(candidates.get(c).substring(4))) listOfPeaksCorresponding.add(hits.get(i).getPeak()); } List<IAtomContainer> hitsListTest = new ArrayList<IAtomContainer>(); for (int i = 0; i < hits.size(); i++) { List<IAtomContainer> hitsList = new ArrayList<IAtomContainer>(); hitsList.add(AtomContainerManipulator.removeHydrogens(hits.get(i).getFragment())); hitsListTest.add(hits.get(i).getFragment()); // Render.Highlight(AtomContainerManipulator.removeHydrogens(molecule), hitsList , // Double.toString(hits.get(i).getPeak())); } if (showDiagrams) Render.Draw(molecule, hitsListTest, "Fragmente von: " + candidates.get(c)); } catch (CDKException e) { System.out.println("CDK error!" + e.getMessage()); completeLog += "CDK Error! " + e.getMessage() + "File: " + candidates.get(c).substring(4); } catch (FileNotFoundException e) { System.out.println("File not found" + e.getMessage()); completeLog += "File not found error! " + e.getMessage() + "File: " + candidates.get(c).substring(4); } catch (IOException e) { System.out.println("IO error: " + e.getMessage()); completeLog += "IO Error! " + e.getMessage() + "File: " + candidates.get(c).substring(4); } catch (Exception e) { System.out.println("Error" + e.getMessage()); completeLog += "Error! " + e.getMessage() + "File: " + candidates.get(c).substring(4); } catch (OutOfMemoryError e) { System.out.println("Out of memory: " + e.getMessage() + "\n" + e.getStackTrace()); System.gc(); completeLog += "Out of memory! " + e.getMessage() + "File: " + candidates.get(c).substring(4); } } // write things to log file foundPeaks += combinedHits; allPeaks += combinedPeakCount; completeLog += "\nFile: " + candidates.get(c).substring(4) + "\t #Peaks: " + combinedPeakCount + "\t #Found: " + combinedHits; completeLog += "\tPeaks: " + peaks; } // easy scoring Integer[] keylist = new Integer[scoreMap.keySet().size()]; Object[] keys = scoreMap.keySet().toArray(); for (int i = 0; i < keys.length; i++) { keylist[i] = Integer.parseInt(keys[i].toString()); } Arrays.sort(keylist); String scoreList = ""; int rank = 0; for (int i = keylist.length - 1; i >= 0; i--) { boolean check = false; for (int j = 0; j < scoreMap.get(keylist[i]).size(); j++) { scoreList += "\n" + keylist[i] + " - " + scoreMap.get(keylist[i]).get(j); if (keggIdentifier.equals(scoreMap.get(keylist[i]).get(j))) { check = true; } // worst case: count all which are better or have a equal position rank++; } if (check) { histogram += "\n" + file + "\t" + keggIdentifier + "\t" + rank + "\t" + exactMass; } } if (keggIdentifier.equals("none")) { histogram += "\n" + file + "\t" + keggIdentifier + "\t\t" + exactMass; } completeLog += "\n\n*****************Scoring*****************************"; completeLog += "Supposed to be: " + keggIdentifier; completeLog += scoreList; completeLog += "\n*****************************************************\n\n"; // easy scoring end // real scoring Double[] keysScore = new Double[realScoreMap.keySet().size()]; keysScore = realScoreMap.keySet().toArray(keysScore); Arrays.sort(keysScore); String scoreListReal = ""; rank = 0; for (int i = keysScore.length - 1; i >= 0; i--) { boolean check = false; for (int j = 0; j < realScoreMap.get(keysScore[i]).size(); j++) { scoreListReal += "\n" + keysScore[i] + " - " + realScoreMap.get(keysScore[i]).get(j); if (keggIdentifier.compareTo(realScoreMap.get(keysScore[i]).get(j)) == 0) { check = true; } // worst case: count all which are better or have a equal position rank++; } if (check) { histogramReal += "\n" + file + "\t" + keggIdentifier + "\t" + rank + "\t" + exactMass; } } if (keggIdentifier.equals("none")) { histogramReal += "\n" + file + "\t" + keggIdentifier + "\t\t" + exactMass; } // timing long timeEnd = System.currentTimeMillis() - timeStart; sumTime += timeEnd; completeLog += "\n\n*****************Scoring(Real)*****************************"; completeLog += "Supposed to be: " + keggIdentifier; completeLog += "\nTime: " + timeEnd; completeLog += scoreListReal; completeLog += "\n*****************************************************\n\n"; // write the data for peak histogram to log file for (int i = 0; i < listOfPeaks.size(); i++) { histogramPeaksAll += listOfPeaks.get(i) + "\n"; } // filter the peaks which are contained in the all peaks list. (exclusive) for (int i = 0; i < listOfPeaksCorresponding.size(); i++) { for (int j = 0; j < listOfPeaks.size(); j++) { Double valueA = listOfPeaks.get(j).getMass(); Double valueB = listOfPeaksCorresponding.get(i).getMass(); if (valueA.compareTo(valueB) == 0) { listOfPeaks.remove(j); } } } for (int i = 0; i < listOfPeaks.size(); i++) { histogramPeaks += listOfPeaks.get(i) + " "; } for (int i = 0; i < listOfPeaksCorresponding.size(); i++) { histogramPeaksReal += listOfPeaksCorresponding.get(i) + " "; } }
/* * this is a test contributed by mario baseda / see bug #1610997 * @cdk.bug 1610997 */ @Test public void testModel3D_bug_1610997() throws Exception { Assume.assumeTrue(runSlowTests()); boolean notCalculatedResults = false; List inputList = new ArrayList(); //////////////////////////////////////////////////////////////////////////////////////////// // generate the input molecules. This are molecules without x, y, z coordinats String[] smiles = new String[] { "CC", "OCC", "O(C)CCC", "c1ccccc1", "C(=C)=C", "OCC=CCc1ccccc1(C=C)", "O(CC=C)CCN", "CCCCCCCCCCCCCCC", "OCC=CCO", "NCCCCN" }; SmilesParser sp = new SmilesParser(NoNotificationChemObjectBuilder.getInstance()); IAtomContainer[] atomContainer = new IAtomContainer[smiles.length]; for (int i = 0; i < smiles.length; i++) { atomContainer[i] = sp.parseSmiles(smiles[i]); inputList.add(atomContainer[i]); } System.out.println(inputList.size()); /////////////////////////////////////////////////////////////////////////////////////////// // Generate 2D coordinats for the input molecules with the Structure Diagram Generator StructureDiagramGenerator str; List resultList = new ArrayList(); for (Iterator iter = inputList.iterator(); iter.hasNext(); ) { IAtomContainer molecules = (IAtomContainer) iter.next(); str = new StructureDiagramGenerator(); str.setMolecule((IMolecule) molecules); str.generateCoordinates(); resultList.add(str.getMolecule()); } inputList = resultList; ///////////////////////////////////////////////////////////////////////////////////////////// // Delete x and y coordinats for (Iterator iter = inputList.iterator(); iter.hasNext(); ) { IAtomContainer molecules = (IAtomContainer) iter.next(); for (Iterator atom = molecules.atoms().iterator(); atom.hasNext(); ) { Atom last = (Atom) atom.next(); last.setPoint2d(null); } } //////////////////////////////////////////////////////////////////////////////////////////////////// // Test for the method Model3DBuildersWithMM2ForceField ModelBuilder3D mb3d = ModelBuilder3D.getInstance(); for (Iterator iter = inputList.iterator(); iter.hasNext(); ) { IAtomContainer molecules = (IAtomContainer) iter.next(); IMolecule mol = molecules.getBuilder().newInstance(IMolecule.class, molecules); mol = mb3d.generate3DCoordinates(mol, false); System.out.println("Calculation done"); } for (Iterator iter = inputList.iterator(); iter.hasNext(); ) { IAtomContainer molecule = (IAtomContainer) iter.next(); checkAverageBondLength(molecule); for (Iterator atom = molecule.atoms().iterator(); atom.hasNext(); ) { Atom last = (Atom) atom.next(); if (last.getPoint3d() == null) notCalculatedResults = true; } } Assert.assertFalse(notCalculatedResults); }
/** * Finds the Smallest Set of Smallest Rings. * * @param mol the molecule to be searched for rings * @return a RingSet containing the rings in molecule */ public IRingSet findSSSR(IAtomContainer mol) { IBond brokenBond = null; IChemObjectBuilder builder = mol.getBuilder(); IRingSet sssr = builder.newInstance(IRingSet.class); IAtomContainer molecule = builder.newInstance(IAtomContainer.class); molecule.add(mol); IAtom smallest; int smallestDegree, nodesToBreakCounter, degree; IAtom[] rememberNodes; IRing ring; // Two Vectors - as defined in the article. One to hold the // full set of atoms in the structure and on to store the numbers // of the nodes that have been trimmed away. // Furhter there is a Vector nodesN2 to store the number of N2 nodes List<IAtom> fullSet = new ArrayList<IAtom>(); List<IAtom> trimSet = new ArrayList<IAtom>(); List<IAtom> nodesN2 = new ArrayList<IAtom>(); initPath(molecule); logger.debug("molecule.getAtomCount(): " + molecule.getAtomCount()); // load fullSet with the numbers of our atoms for (int f = 0; f < molecule.getAtomCount(); f++) { fullSet.add(molecule.getAtom(f)); } logger.debug("fullSet.size(): " + fullSet.size()); do { // Add nodes of degree zero to trimset. // Also add nodes of degree 2 to nodesN2. // In the same run, check, which node has the lowest degree // greater than zero. smallestDegree = 7; smallest = null; nodesN2.clear(); for (int f = 0; f < molecule.getAtomCount(); f++) { IAtom atom = molecule.getAtom(f); degree = molecule.getConnectedBondsCount(atom); if (degree == 0) { if (!trimSet.contains(atom)) { logger.debug("Atom of degree 0"); trimSet.add(atom); } } if (degree == 2) { nodesN2.add(atom); } if (degree < smallestDegree && degree > 0) { smallest = atom; smallestDegree = degree; } } if (smallest == null) break; // If there are nodes of degree 1, trim them away if (smallestDegree == 1) { trimCounter++; trim(smallest, molecule); trimSet.add(smallest); } // if there are nodes of degree 2, find out of which rings // they are part of. else if (smallestDegree == 2) { rememberNodes = new IAtom[nodesN2.size()]; nodesToBreakCounter = 0; for (int f = 0; f < nodesN2.size(); f++) { ring = getRing((IAtom) nodesN2.get(f), molecule); if (ring != null) { // check, if this ring already is in SSSR if (!RingSetManipulator.ringAlreadyInSet(ring, sssr)) { sssr.addAtomContainer(ring); rememberNodes[nodesToBreakCounter] = (IAtom) nodesN2.get(f); nodesToBreakCounter++; } } } if (nodesToBreakCounter == 0) { nodesToBreakCounter = 1; rememberNodes[0] = (IAtom) nodesN2.get(0); } for (int f = 0; f < nodesToBreakCounter; f++) { breakBond(rememberNodes[f], molecule); } if (brokenBond != null) { molecule.addBond(brokenBond); brokenBond = null; } } // if there are nodes of degree 3 else if (smallestDegree == 3) { ring = getRing(smallest, molecule); if (ring != null) { // check, if this ring already is in SSSR if (!RingSetManipulator.ringAlreadyInSet(ring, sssr)) { sssr.addAtomContainer(ring); } brokenBond = checkEdges(ring, molecule); molecule.removeElectronContainer(brokenBond); } } } while (trimSet.size() < fullSet.size()); logger.debug("fullSet.size(): " + fullSet.size()); logger.debug("trimSet.size(): " + trimSet.size()); logger.debug("trimCounter: " + trimCounter); // molecule.setProperty(CDKConstants.SMALLEST_RINGS, sssr); return sssr; }
/** A unit test for JUnit */ @Test public void testCisTransDecalin() throws Exception { HydrogenPlacer hydrogenPlacer = new HydrogenPlacer(); IAtomContainer mol1 = new AtomContainer(); SmilesGenerator sg = new SmilesGenerator(); mol1.addAtom(new Atom("H", new Point2d(1, 0))); // 1 mol1.addAtom(new Atom("C", new Point2d(1, 2))); // 2 mol1.addAtom(new Atom("C", new Point2d(1, 2))); // 3 mol1.addAtom(new Atom("C", new Point2d(0, 0))); // 4 mol1.addAtom(new Atom("C", new Point2d(1, 4))); // 5 mol1.addAtom(new Atom("C", new Point2d(1, 5))); // 6 mol1.addAtom(new Atom("C", new Point2d(1, 6))); // 7 mol1.addAtom(new Atom("H", new Point2d(1, 0))); // 1 mol1.addAtom(new Atom("C", new Point2d(1, 2))); // 2 mol1.addAtom(new Atom("C", new Point2d(1, 2))); // 3 mol1.addAtom(new Atom("C", new Point2d(1, 2))); // 2 mol1.addAtom(new Atom("C", new Point2d(1, 2))); // 3 mol1.addBond(0, 1, IBond.Order.SINGLE, IBond.Stereo.DOWN); // 1 mol1.addBond(1, 2, IBond.Order.SINGLE); // 2 mol1.addBond(2, 3, IBond.Order.SINGLE); // 3 mol1.addBond(3, 4, IBond.Order.SINGLE); // 4 mol1.addBond(4, 5, IBond.Order.SINGLE); // 5 mol1.addBond(5, 6, IBond.Order.SINGLE); // 6 mol1.addBond(6, 7, IBond.Order.SINGLE, IBond.Stereo.DOWN); // 3 mol1.addBond(6, 8, IBond.Order.SINGLE); // 4 mol1.addBond(8, 9, IBond.Order.SINGLE); // 5 mol1.addBond(9, 10, IBond.Order.SINGLE); // 6 mol1.addBond(10, 11, IBond.Order.SINGLE); // 6 mol1.addBond(11, 1, IBond.Order.SINGLE); // 6 mol1.addBond(1, 6, IBond.Order.SINGLE); // 6 try { addExplicitHydrogens(mol1); hydrogenPlacer.placeHydrogens2D(mol1, 1.0); IsotopeFactory ifac = IsotopeFactory.getInstance(mol1.getBuilder()); ifac.configureAtoms(mol1); } catch (IOException ex) { } catch (ClassNotFoundException ex) { } String smiles1 = null; if (standAlone) { display(mol1); } try { smiles1 = sg.createSMILES(mol1, true, new boolean[mol1.getBondCount()]); } catch (Exception exc) { System.out.println(exc); if (!standAlone) { Assert.fail(); } } if (standAlone) { System.err.println("SMILES 1: " + smiles1); } Assert.assertNotNull(smiles1); Assert.assertEquals( "[H]C1([H])(C([H])([H])C([H])([H])C\\2([H])(C([H])([H])C([H])([H])C([H])([H])C([H])([H])C\\2([H])(C1([H])([H]))))", smiles1); mol1.getBond(6).setStereo(IBond.Stereo.UP); String smiles3 = null; try { smiles3 = sg.createSMILES(mol1, true, new boolean[mol1.getBondCount()]); } catch (Exception exc) { System.out.println(exc); if (!standAlone) { Assert.fail(); } } Assert.assertNotSame(smiles3, smiles1); }
/** A unit test for JUnit */ @Test public void testDoubleBondConfiguration() throws Exception { HydrogenPlacer hydrogenPlacer = new HydrogenPlacer(); IAtomContainer mol1 = new AtomContainer(); SmilesGenerator sg = new SmilesGenerator(); mol1.addAtom(new Atom("S", new Point2d(0, 0))); // 1 mol1.addAtom(new Atom("C", new Point2d(1, 1))); // 2 mol1.addAtom(new Atom("F", new Point2d(2, 0))); // 3 mol1.addAtom(new Atom("C", new Point2d(1, 2))); // 4 mol1.addAtom(new Atom("F", new Point2d(2, 3))); // 5 mol1.addAtom(new Atom("S", new Point2d(0, 3))); // 1 mol1.addBond(0, 1, IBond.Order.SINGLE); // 1 mol1.addBond(1, 2, IBond.Order.SINGLE); // 2 mol1.addBond(1, 3, IBond.Order.DOUBLE); // 3 mol1.addBond(3, 4, IBond.Order.SINGLE); // 4 mol1.addBond(3, 5, IBond.Order.SINGLE); // 4 try { IsotopeFactory ifac = IsotopeFactory.getInstance(mol1.getBuilder()); ifac.configureAtoms(mol1); } catch (IOException ex) { } String smiles1 = null; if (standAlone) { display(mol1); } boolean[] bool = new boolean[mol1.getBondCount()]; bool[2] = true; try { smiles1 = sg.createSMILES(mol1, true, bool); } catch (Exception exc) { System.out.println(exc); if (!standAlone) { Assert.fail(); } } if (standAlone) { System.err.println("SMILES 1: " + smiles1); } Assert.assertNotNull(smiles1); Assert.assertEquals("F/C(=C/(F)S)S", smiles1); mol1.getAtom(4).setPoint2d(new Point2d(0, 3)); mol1.getAtom(5).setPoint2d(new Point2d(2, 3)); try { smiles1 = sg.createSMILES(mol1, true, bool); } catch (Exception exc) { System.out.println(exc); if (!standAlone) { Assert.fail(); } } if (standAlone) { System.err.println("SMILES 1: " + smiles1); } Assert.assertNotNull(smiles1); Assert.assertEquals("F/C(=C\\(F)S)S", smiles1); try { addExplicitHydrogens(mol1); hydrogenPlacer.placeHydrogens2D(mol1, 1.0); } catch (IOException ex) { } catch (ClassNotFoundException ex) { } bool = new boolean[mol1.getBondCount()]; bool[2] = true; try { smiles1 = sg.createSMILES(mol1, true, bool); } catch (Exception exc) { System.out.println(exc); if (!standAlone) { Assert.fail(); } } Assert.assertEquals("[H]S/C(F)=C/(F)S[H]", smiles1); mol1.getAtom(5).setPoint2d(new Point2d(0, 3)); mol1.getAtom(4).setPoint2d(new Point2d(2, 3)); try { smiles1 = sg.createSMILES(mol1, true, bool); } catch (Exception exc) { System.out.println(exc); if (!standAlone) { Assert.fail(); } } Assert.assertEquals("[H]S/C(F)=C\\(F)S[H]", smiles1); }
/** * Calculates the 3 MI's, 3 ration and the R_gyr value. * * <p>The molecule should have hydrogens * * @param container Parameter is the atom container. * @return An ArrayList containing 7 elements in the order described above */ @TestMethod("testCalculate_IAtomContainer") public DescriptorValue calculate(IAtomContainer container) { if (!GeometryTools.has3DCoordinates(container)) return getDummyDescriptorValue(new CDKException("Molecule must have 3D coordinates")); IAtomContainer clone; IsotopeFactory factory; try { clone = (IAtomContainer) container.clone(); factory = IsotopeFactory.getInstance(container.getBuilder()); factory.configureAtoms(clone); } catch (Exception e) { logger.debug(e); return getDummyDescriptorValue(e); } DoubleArrayResult retval = new DoubleArrayResult(7); double ccf = 1.000138; double eps = 1e-5; double[][] imat = new double[3][3]; Point3d centerOfMass = GeometryTools.get3DCentreOfMass(clone); double xdif; double ydif; double zdif; double xsq; double ysq; double zsq; for (int i = 0; i < clone.getAtomCount(); i++) { IAtom currentAtom = clone.getAtom(i); double mass = factory.getMajorIsotope(currentAtom.getSymbol()).getExactMass(); xdif = currentAtom.getPoint3d().x - centerOfMass.x; ydif = currentAtom.getPoint3d().y - centerOfMass.y; zdif = currentAtom.getPoint3d().z - centerOfMass.z; xsq = xdif * xdif; ysq = ydif * ydif; zsq = zdif * zdif; imat[0][0] += mass * (ysq + zsq); imat[1][1] += mass * (xsq + zsq); imat[2][2] += mass * (xsq + ysq); imat[1][0] += -1 * mass * ydif * xdif; imat[0][1] = imat[1][0]; imat[2][0] += -1 * mass * xdif * zdif; imat[0][2] = imat[2][0]; imat[2][1] += -1 * mass * ydif * zdif; imat[1][2] = imat[2][1]; } // diagonalize the MI tensor Matrix tmp = new Matrix(imat); EigenvalueDecomposition eigenDecomp = tmp.eig(); double[] eval = eigenDecomp.getRealEigenvalues(); retval.add(eval[2]); retval.add(eval[1]); retval.add(eval[0]); double etmp = eval[0]; eval[0] = eval[2]; eval[2] = etmp; if (Math.abs(eval[1]) > 1e-3) retval.add(eval[0] / eval[1]); else retval.add(1000); if (Math.abs(eval[2]) > 1e-3) { retval.add(eval[0] / eval[2]); retval.add(eval[1] / eval[2]); } else { retval.add(1000); retval.add(1000); } // finally get the radius of gyration double pri; IMolecularFormula formula = MolecularFormulaManipulator.getMolecularFormula(clone); if (Math.abs(eval[2]) > eps) pri = Math.pow(eval[0] * eval[1] * eval[2], 1.0 / 3.0); else pri = Math.sqrt(eval[0] * ccf / MolecularFormulaManipulator.getTotalExactMass(formula)); retval.add( Math.sqrt( Math.PI * 2 * pri * ccf / MolecularFormulaManipulator.getTotalExactMass(formula))); return new DescriptorValue( getSpecification(), getParameterNames(), getParameters(), retval, getDescriptorNames()); }