/* $RCSfile$ * $Author$ * $Date$ * $Revision$ * * Copyright (C) 2005-2007 The Chemistry Development Kit (CDK) project * * 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; either version 2.1 * of the License, or (at your option) any later version. * All we ask is that proper credit is given for our work, which includes * - but is not limited to - adding the above copyright notice to the beginning * of your source code files, and to any copyright notice that you may distribute * with programs based on this work. * * 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.libio.cml; import java.util.Iterator; import java.util.Map; import nu.xom.Attribute; import nu.xom.Element; import org.openscience.cdk.exception.CDKException; import org.openscience.cdk.interfaces.IAtom; import org.openscience.cdk.interfaces.IAtomContainer; import org.openscience.cdk.interfaces.IBond; import org.openscience.cdk.interfaces.IChemObject; import org.openscience.cdk.qsar.DescriptorSpecification; import org.openscience.cdk.qsar.DescriptorValue; import org.openscience.cdk.qsar.result.BooleanResult; import org.openscience.cdk.qsar.result.DoubleArrayResult; import org.openscience.cdk.qsar.result.DoubleResult; import org.openscience.cdk.qsar.result.IDescriptorResult; import org.openscience.cdk.qsar.result.IntegerArrayResult; import org.openscience.cdk.qsar.result.IntegerResult; import org.xmlcml.cml.element.CMLArray; import org.xmlcml.cml.element.CMLMetadata; import org.xmlcml.cml.element.CMLMetadataList; import org.xmlcml.cml.element.CMLProperty; import org.xmlcml.cml.element.CMLPropertyList; import org.xmlcml.cml.element.CMLScalar; /** * Customizer for the libio-cml Convertor to be able to export details for * QSAR descriptors calculated for Molecules. * * @author egonw * @cdk.created 2005-05-04 * @cdk.module qsarcml * @cdk.githash * @cdk.set libio-cml-customizers * @cdk.require java1.5+ */ public class QSARCustomizer implements ICMLCustomizer { private final static String QSAR_NAMESPACE = "qsar"; private final static String QSAR_URI = "http://www.blueobelisk.org/ontologies/chemoinformatics-algorithms/"; public void customize(IBond bond, Object nodeToAdd) throws Exception { customizeIChemObject(bond, nodeToAdd); } public void customize(IAtom atom, Object nodeToAdd) throws Exception { customizeIChemObject(atom, nodeToAdd); } public void customize(IAtomContainer molecule, Object nodeToAdd) throws Exception { customizeIChemObject(molecule, nodeToAdd); } private Element createScalar(IDescriptorResult value) { Element scalar = null; if (value instanceof DoubleResult) { scalar = new CMLScalar(); scalar.addAttribute(new Attribute("dataType", "xsd:double")); scalar.appendChild("" + ((DoubleResult)value).doubleValue()); } else if (value instanceof IntegerResult) { scalar = new CMLScalar(); scalar.addAttribute(new Attribute("dataType", "xsd:int")); scalar.appendChild("" + ((IntegerResult)value).intValue()); } else if (value instanceof BooleanResult) { scalar = new CMLScalar(); scalar.addAttribute(new Attribute("dataType", "xsd:boolean")); scalar.appendChild("" + ((BooleanResult)value).booleanValue()); } else if (value instanceof IntegerArrayResult) { IntegerArrayResult result = (IntegerArrayResult)value; scalar = new CMLArray(); scalar.addAttribute(new Attribute("dataType", "xsd:int")); scalar.addAttribute(new Attribute("size", "" + result.length())); StringBuffer buffer = new StringBuffer(); for (int i=0; i<result.length(); i++) { buffer.append(result.get(i) + " "); } scalar.appendChild(buffer.toString()); } else if (value instanceof DoubleArrayResult) { DoubleArrayResult result = (DoubleArrayResult)value; scalar = new CMLArray(); scalar.addAttribute(new Attribute("dataType", "xsd:double")); scalar.addAttribute(new Attribute("size", "" + result.length())); StringBuffer buffer = new StringBuffer(); for (int i=0; i<result.length(); i++) { buffer.append(result.get(i) + " "); } scalar.appendChild(buffer.toString()); } else { // logger.error("Could not convert this object to a scalar element: ", value); scalar.appendChild(value.toString()); } return scalar; } private void customizeIChemObject(IChemObject object, Object nodeToAdd) throws Exception { if (!(nodeToAdd instanceof Element)) throw new CDKException("NodeToAdd must be of type nu.xom.Element!"); Element element = (Element)nodeToAdd; Map<Object,Object> props = object.getProperties(); Iterator<Object> keys = props.keySet().iterator(); Element propList = null; while (keys.hasNext()) { Object key = keys.next(); if (key instanceof DescriptorSpecification) { DescriptorSpecification specs = (DescriptorSpecification)key; DescriptorValue value = (DescriptorValue)props.get(key); IDescriptorResult result = value.getValue(); if (propList == null) { propList = new CMLPropertyList(); } Element property = new CMLProperty(); // setup up the metadata list Element metadataList = new CMLMetadataList(); metadataList.addNamespaceDeclaration(QSAR_NAMESPACE, QSAR_URI); property.addAttribute(new Attribute("convention", QSAR_NAMESPACE + ":" + "DescriptorValue")); String specsRef = specs.getSpecificationReference(); if (specsRef.startsWith(QSAR_URI)) { property.addNamespaceDeclaration(QSAR_NAMESPACE, QSAR_URI); } CMLMetadata metaData = new CMLMetadata(); metaData.addAttribute(new Attribute("dictRef", QSAR_NAMESPACE + ":" + "specificationReference")); metaData.addAttribute(new Attribute("content", specsRef)); metadataList.appendChild(metaData); metaData = new CMLMetadata(); metaData.addAttribute(new Attribute("dictRef", QSAR_NAMESPACE + ":" + "implementationTitle")); metaData.addAttribute(new Attribute("content", specs.getImplementationTitle())); metadataList.appendChild(metaData); metaData = new CMLMetadata(); metaData.addAttribute(new Attribute("dictRef", QSAR_NAMESPACE + ":" + "implementationIdentifier")); metaData.addAttribute(new Attribute("content", specs.getImplementationIdentifier())); metadataList.appendChild(metaData); metaData = new CMLMetadata(); metaData.addAttribute(new Attribute("dictRef", QSAR_NAMESPACE + ":" + "implementationVendor")); metaData.addAttribute(new Attribute("content", specs.getImplementationVendor())); metadataList.appendChild(metaData); // add parameter setting to the metadata list Object[] params = value.getParameters(); // logger.debug("Value: " + value.getSpecification().getImplementationIdentifier()); if (params != null && params.length > 0) { String[] paramNames = value.getParameterNames(); Element paramSettings = new CMLMetadataList(); paramSettings.addAttribute(new Attribute("title", QSAR_NAMESPACE + ":" + "descriptorParameters")); for (int i=0; i<params.length; i++) { Element paramSetting = new CMLMetadata(); String paramName = paramNames[i]; Object paramVal = params[i]; if (paramName == null) { // logger.error("Parameter name was null! Cannot output to CML."); } else if (paramVal == null) { // logger.error("Parameter setting was null! Cannot output to CML. Problem param: " + paramName); } else { paramSetting.addAttribute(new Attribute("title", paramNames[i])); paramSetting.addAttribute(new Attribute("content", params[i].toString())); paramSettings.appendChild(paramSetting); } } metadataList.appendChild(paramSettings); } property.appendChild(metadataList); Element scalar = this.createScalar(result); scalar.addAttribute(new Attribute("dictRef", specsRef)); // add the actual descriptor value property.appendChild(scalar); propList.appendChild(property); } // else: disregard all other properties } if (propList != null) { element.appendChild(propList); } } }