/* $Revision$ $Author$ $Date$ * * Copyright (C) 2008 Egon Willighagen <egonw@users.sf.net> * * Contact: cdk-devel@lists.sourceforge.net * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation, version 2.1. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. */ package org.openscience.cdk.atomtype; import java.io.InputStream; import java.util.Hashtable; import java.util.Map; import org.openscience.cdk.CDKConstants; import org.openscience.cdk.annotations.TestClass; import org.openscience.cdk.annotations.TestMethod; import org.openscience.cdk.aromaticity.CDKHueckelAromaticityDetector; import org.openscience.cdk.atomtype.mapper.AtomTypeMapper; import org.openscience.cdk.config.AtomTypeFactory; import org.openscience.cdk.exception.CDKException; import org.openscience.cdk.interfaces.IAtom; import org.openscience.cdk.interfaces.IAtomContainer; import org.openscience.cdk.interfaces.IAtomType; import org.openscience.cdk.interfaces.IChemObjectBuilder; /** * Atom Type matcher for Sybyl atom types. It uses the {@link CDKAtomTypeMatcher} * for perception and then maps CDK to Sybyl atom types. * * @author egonw * @cdk.created 2008-07-13 * @cdk.module atomtype * @cdk.githash * @cdk.keyword atom type, Sybyl */ @TestClass("org.openscience.cdk.atomtype.SybylAtomTypeMatcherTest") public class SybylAtomTypeMatcher implements IAtomTypeMatcher { private final static String SYBYL_ATOM_TYPE_LIST = "org/openscience/cdk/dict/data/sybyl-atom-types.owl"; private final static String CDK_TO_SYBYL_MAP = "org/openscience/cdk/dict/data/cdk-sybyl-mappings.owl"; private AtomTypeFactory factory; private CDKAtomTypeMatcher cdkMatcher; private AtomTypeMapper mapper; private static Map<IChemObjectBuilder,SybylAtomTypeMatcher> factories = new Hashtable<IChemObjectBuilder,SybylAtomTypeMatcher>(1); private SybylAtomTypeMatcher(IChemObjectBuilder builder) { InputStream stream = this.getClass().getClassLoader().getResourceAsStream(SYBYL_ATOM_TYPE_LIST); factory = AtomTypeFactory.getInstance(stream, "owl", builder); cdkMatcher = CDKAtomTypeMatcher.getInstance(builder); InputStream mapStream = this.getClass().getClassLoader().getResourceAsStream(CDK_TO_SYBYL_MAP); mapper = AtomTypeMapper.getInstance(CDK_TO_SYBYL_MAP, mapStream); } @TestMethod("testGetInstance_IChemObjectBuilder") public static SybylAtomTypeMatcher getInstance(IChemObjectBuilder builder) { if (!factories.containsKey(builder)) factories.put(builder, new SybylAtomTypeMatcher(builder)); return factories.get(builder); } @TestMethod("testFindMatchingAtomType_IAtomContainer") public IAtomType[] findMatchingAtomType(IAtomContainer atomContainer) throws CDKException { for (IAtom atom : atomContainer.atoms()) { IAtomType type = cdkMatcher.findMatchingAtomType(atomContainer, atom); atom.setAtomTypeName(type == null ? null : type.getAtomTypeName()); atom.setHybridization(type == null ? null : type.getHybridization()); } CDKHueckelAromaticityDetector.detectAromaticity(atomContainer); IAtomType[] types = new IAtomType[atomContainer.getAtomCount()]; int typeCounter = 0; for (IAtom atom : atomContainer.atoms()) { String mappedType = mapCDKToSybylType(atom); if (mappedType == null) { types[typeCounter] = null; } else { types[typeCounter] = factory.getAtomType(mappedType); } typeCounter++; } return types; } /** * Sybyl atom type perception for a single atom. The molecular property <i>aromaticity</i> is not perceived; * Aromatic carbons will, therefore, be perceived as <i>C.2</i> and not <i>C.ar</i>. If the latter is * required, please use findMatchingAtomType(IAtomContainer) instead. */ @TestMethod("testFindMatchingAtomType_IAtomContainer_IAtom") public IAtomType findMatchingAtomType(IAtomContainer atomContainer, IAtom atom) throws CDKException { IAtomType type = cdkMatcher.findMatchingAtomType(atomContainer, atom); if (type == null) return null; else atom.setAtomTypeName(type.getAtomTypeName()); String mappedType = mapCDKToSybylType(atom); if (mappedType == null) return null; return factory.getAtomType(mappedType); } private String mapCDKToSybylType(IAtom atom) { String typeName = atom.getAtomTypeName(); if (typeName == null) return null; String mappedType = mapper.mapAtomType(typeName); if ("C.2".equals(mappedType) && atom.getFlag(CDKConstants.ISAROMATIC)) { mappedType = "C.ar"; } else if ("N.2".equals(mappedType) && atom.getFlag(CDKConstants.ISAROMATIC)) { mappedType = "N.ar"; } else if ("N.pl3".equals(mappedType) && atom.getFlag(CDKConstants.ISAROMATIC)) { mappedType = "N.ar"; } return mappedType; } }