Commits

petermr committed 92e2733

first commit

Comments (0)

Files changed (19)

+foo
+^.project$
+^.settings/
+^.classpath$
+^.hgignore~$
+^target/.*
+/target/
+<?xml version="1.0" encoding="UTF-8"?>
+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+   <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>cml</groupId>
+        <artifactId>jumbo-converters</artifactId>
+        <version>0.3-SNAPSHOT</version>
+    </parent>
+
+   <artifactId>jumbo-converters-reaction</artifactId>
+
+   <name>jumbo-converters-reaction</name>
+
+   <dependencies>
+      <dependency>
+         <groupId>cml</groupId>
+         <artifactId>jumbo-converters-core</artifactId>
+      </dependency>
+      <dependency>
+         <groupId>cml</groupId>
+         <artifactId>jumbo-converters-rdf</artifactId>
+      </dependency>
+      <dependency>
+         <groupId>${cml.groupId}</groupId>
+         <artifactId>jumbo-units</artifactId>
+         <version>${jumbounits.version}</version>
+      </dependency>
+
+      <dependency>
+         <groupId>junit</groupId>
+         <artifactId>junit</artifactId>
+         <scope>test</scope>
+      </dependency>
+   </dependencies>
+
+</project>

src/main/java/org/xmlcml/cml/converters/reaction/ReactionMergeDiff.java

+package org.xmlcml.cml.converters.reaction;
+
+import java.io.StringReader;
+import java.util.List;
+
+import nu.xom.Element;
+import nu.xom.Nodes;
+
+import org.apache.log4j.Level;
+import org.apache.log4j.Logger;
+import org.xmlcml.cml.base.CMLBuilder;
+import org.xmlcml.cml.base.CMLConstants;
+import org.xmlcml.cml.base.CMLElement;
+import org.xmlcml.cml.base.CMLUtil;
+import org.xmlcml.cml.converters.AbstractConverter;
+import org.xmlcml.cml.converters.MergeDiff;
+import org.xmlcml.cml.converters.MimeType;
+import org.xmlcml.cml.converters.cml.CMLCommon;
+import org.xmlcml.cml.element.CMLActionList;
+import org.xmlcml.cml.element.CMLParameterList;
+import org.xmlcml.cml.element.CMLProductList;
+import org.xmlcml.cml.element.CMLReactantList;
+import org.xmlcml.cml.element.CMLReaction;
+import org.xmlcml.cml.element.CMLSubstanceList;
+
+/** reads reactions in MMreRDF format.
+ * converts to CMLReact
+ * @author pm286
+ *
+ */
+public class ReactionMergeDiff extends AbstractConverter implements MergeDiff {
+	private static final Logger LOG = Logger.getLogger(ReactionMergeDiff.class);
+	static {
+		LOG.setLevel(Level.DEBUG);
+	};
+	
+	private CMLElement cmlElement;
+	private List<String> xpathList;
+	private Element mergedElement;
+	
+	/**
+	 * converts an XYZ object to CML. returns cml:cml/cml:molecule
+	 * 
+	 * @param xml
+	 */
+	public Element convertToXML(Element xml) {
+		if (xml == null) {
+			throw new RuntimeException("null xml input");
+		}
+		String xmlS = CMLUtil.getCanonicalString(xml);
+		Element element = null;
+		try {
+			element = new CMLBuilder().build(new StringReader(xmlS)).getRootElement();
+		} catch (Exception e) {
+			throw new RuntimeException("cannot parse xml? BUG?");
+		}
+		Element auxElement = getAuxElement();
+		if (auxElement == null) {
+			throw new RuntimeException("Null or corrupt auxiliary file ");
+		}
+		cmlElement = null;
+		diff(element, auxElement);
+		return cmlElement;
+	}
+	
+	public Element merge(Element element1, Element element2) {
+		Element element = null;
+		return element;
+	}
+	
+	public Element diff(Element element1, Element element2) {
+		CMLReaction reaction1 = getSingleReaction(element1);
+		CMLReaction reaction2 = getSingleReaction(element2);
+		Element element = diff(reaction1, reaction2);
+		return element;
+	}
+	
+	private CMLReaction getSingleReaction(Element element) {
+		if (!(element instanceof CMLElement)) {
+			throw new RuntimeException("element1 is not CML: "+element.getLocalName());
+		}
+		Nodes reactions1 = element.query(".//cml:reaction", CMLConstants.CML_XPATH);
+		if (reactions1.size() != 1) {
+			throw new RuntimeException("Need exactly one reaction in element1");
+		}
+		return (CMLReaction) reactions1.get(0);
+	}
+
+/**
+ <reaction>
+  <reactantList>
+   <reactant>
+    <molecule ref="37">
+     <label value="172" cdx:BoundingBox="153.3052 67.6844 168.3052 76.7344" cdx:ydelta="-3.702999999999996"/>
+    </molecule>
+   </reactant>
+   <reactant title="DIBAL-H" role="cml:reagent" dictRef="cmlreag:DIBAL-H"/>
+  </reactantList>
+  <productList>
+   <product>
+    <molecule ref="70">
+     <label value="173" cdx:BoundingBox="337.1213 70.6814 352.1213 79.7314" cdx:ydelta="-5.200000000000003"/>
+    </molecule>
+   </product>
+  </productList>
+  <substanceList>
+   <substance title="THF" role="cml:solvent" dictRef="cmlrepo:THF"/>
+  </substanceList>
+  <conditionList>
+   <parameter role="temperature">
+    <scalar dataType="xsd:double" units="units:c">-78.0</scalar>
+   </parameter>
+   <parameter role="duration">
+    <scalar dataType="xsd:double" units="units:hour">1.0</scalar>
+   </parameter>
+  </conditionList>
+ </reaction>
+
+  <reaction id="Harter-preparation-1">
+    <action role="cml:washed" id="rrpPeTyd897">
+      <amount units="unit:ml" dictRef="cml:volume" id="rrpPeTyd899">150.0</amount>
+      <name>Et2O</name>
+    </action>
+    <action role="cml:purified" id="rrpPeTyd901">
+      <action role="cml:chromatography">flash column chromatography</action>
+    </action>
+    <reactantList>
+      <reactant id="Harter_172">
+        <amount units="unit:mmol" dictRef="cml:molarAmount" id="rrpPeTyd876">7.68</amount>
+        <label role="cml:serialNumber">172</label>
+        <name>epoxide ester</name>
+        <amount units="unit:gram" dictRef="cml:mass" id="rrpPeTyd875">1.2</amount>
+      </reactant>
+      <reactant role="reagent" id="rrpPeTyd877">
+        <amount units="unit:mmol" dictRef="cml:molarAmount" id="rrpPeTyd880">17.7</amount>
+        <name>Diisobutylaluminium hydride</name>
+        <amount units="unit:ml" dictRef="cml:volume" id="rrpPeTyd879">17.7</amount>
+      </reactant>
+      <reactant role="reagent" id="rrpPeTyd887">
+        <amount units="unit:ml" dictRef="cml:volume" id="rrpPeTyd889">8.0</amount>
+        <name>Triethanolamine</name>
+      </reactant>
+      <reactant role="reagent" id="rrpPeTyd884">
+        <amount units="unit:ml" dictRef="cml:volume" id="rrpPeTyd886">10.0</amount>
+        <name>methanol</name>
+      </reactant>
+    </reactantList>
+    <productList>
+      <product id="Harter_173">
+        <property dictRef="cml:state">oil</property>
+        <amount units="unit:percent" dictRef="cml:percent" id="rrpPeTyd895">82.0</amount>
+        <label role="cml:serialNumber">173</label>
+        <name>alcohol</name>
+        <name>(2E,4R*,5R*)-4,5-epoxy-hex-2-en-1-ol</name>
+        <amount units="unit:mmol" dictRef="cml:molarAmount" id="rrpPeTyd894">6.29</amount>
+        <amount units="unit:mg" dictRef="cml:mass" id="rrpPeTyd893">718.0</amount>
+      </product>
+    </productList>
+    <substanceList>
+      <substance role="solvent" id="rrpPeTyd881">
+        <amount units="unit:ml" dictRef="cml:volume" id="rrpPeTyd883">10.0</amount>
+        <name>THF</name>
+      </substance>
+    </substanceList>
+    <parameterList>
+      <parameter dictRef="cml:time" units="unit:hour" id="rrpPeTyd890">
+        <scalar dataType="xsd:double">18.0</scalar>
+      </parameter>
+      <parameter dictRef="cml:temp" units="unit:celsius" id="rrpPeTyd891">
+        <scalar dataType="xsd:double">7.0</scalar>
+      </parameter>
+    </parameterList>
+  </reaction>
+
+  <reactant id="Harter_172">
+    <amount units="unit:mmol" dictRef="cml:molarAmount" id="rrpPeTyd876">7.68</amount>
+    <label role="cml:serialNumber">172</label>
+    <name>epoxide ester</name>
+    <amount units="unit:gram" dictRef="cml:mass" id="rrpPeTyd875">1.2</amount>
+  </reactant>
+      
+  <reactant>
+   <molecule ref="37">
+    <label value="172" cdx:BoundingBox="153.3052 67.6844 168.3052 76.7344" cdx:ydelta="-3.702999999999996"/>
+   </molecule>
+  </reactant>
+   
+      reactantProductXPathList = 
+          "./cml:label" ... "./cml:molecule/cml:label/@value"
+          
+      <substance role="solvent" id="rrpPeTyd881">
+        <amount units="unit:ml" dictRef="cml:volume" id="rrpPeTyd883">10.0</amount>
+        <name>THF</name>
+      </substance>
+      
+   <substance title="THF" role="cml:solvent" dictRef="cmlrepo:THF"/>
+
+      solventXPathList = 
+          "./cml:name" ... "./@title"
+          
+ * 
+ * 
+ * @param reaction1
+ * @param reaction2
+ * @return
+ */	
+	private Element diff(CMLReaction reaction1, CMLReaction reaction2) {
+//		xpathList = getCommand().getXPathList();
+		String rootXpath = ".//cml:reactant";
+		compareElements(reaction1, reaction2, rootXpath, 0, 1);
+		rootXpath = ".//cml:product";
+		compareElements(reaction1, reaction2, rootXpath, 0, 1);
+		rootXpath = ".//cml:substance";
+		compareElements(reaction1, reaction2, rootXpath, 2, 3);
+		makeMergedReaction();
+		return mergedElement;
+	}
+	
+	private void makeMergedReaction() {
+		mergedElement = new CMLReaction();
+		CMLReactantList reactantList = new CMLReactantList();
+		CMLProductList productList = new CMLProductList();
+		CMLSubstanceList substanceList = new CMLSubstanceList();
+		CMLActionList actionList = new CMLActionList();
+		CMLParameterList parameterList = new CMLParameterList();
+		mergedElement.appendChild(reactantList);
+		mergedElement.appendChild(productList);
+		mergedElement.appendChild(substanceList);
+		mergedElement.appendChild(parameterList);
+		mergedElement.appendChild(actionList);
+	}
+
+private void compareElements(CMLReaction reaction1, CMLReaction reaction2,
+		String rootXpath, int xPath1, int xPath2) {
+	
+	List<CMLElement> reactants1 = CMLUtil.getCMLElements(
+			reaction1, rootXpath, CMLConstants.CML_XPATH);
+	List<CMLElement> reactants2 = CMLUtil.getCMLElements(
+			reaction2, rootXpath, CMLConstants.CML_XPATH);
+	
+	for (CMLElement element1 : reactants1) {
+		for (CMLElement element2 : reactants2) {
+			Double agreement = getAgreementWith(element1, xpathList.get(xPath1), element2, xpathList.get(xPath2));
+			if (agreement > 0.99) {
+//				element1.mergeElement(element2, Merge.OVERWRITE);
+			}
+		}
+	}
+}
+	
+	private Double getAgreementWith(CMLElement element1, String xpath1, 
+			CMLElement element2, String xpath2) {
+		Nodes nodes1 = element1.query(xpath1, CMLConstants.CML_XPATH);
+		String s1 = (nodes1.size() > 0) ? nodes1.get(0).getValue() : null;
+		Nodes nodes2 = element2.query(xpath2, CMLConstants.CML_XPATH);
+		String s2 = (nodes2.size() > 0) ? nodes2.get(0).getValue() : null;
+		LOG.debug(""+s1 + " ... "+s2);
+		Double d = 0.0;
+		if (s1 != null && s1.equals(s2)) {
+			d = 1.0;
+		}
+		return d;
+	}
+	
+	public MimeType getInputType() {
+		return CMLCommon.CML_TYPE;
+	}
+	
+	public MimeType getOutputType() {
+		return CMLCommon.CML_TYPE;
+	}
+	
+	public String getDescription() {
+		return "null";
+	}
+
+}
+

src/main/java/org/xmlcml/cml/converters/reaction/ReactionModule.java

+package org.xmlcml.cml.converters.reaction;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.xmlcml.cml.converters.Converter;
+import org.xmlcml.cml.converters.MimeType;
+import org.xmlcml.cml.converters.MimeType.ObjectType;
+import org.xmlcml.cml.converters.registry.AbstractConverterModule;
+
+/**
+ * @author Sam Adams
+ */
+public class ReactionModule extends AbstractConverterModule {
+
+	public static final MimeType RXN_TYPE = new MimeType("chemical/x-mdl-rxnfile", ObjectType.TEXT, "rxn");
+	private static final String PREFIX = "reaction";
+	
+    public String getPrefix() {
+    	return PREFIX;
+    }
+
+    public ReactionModule() {
+    	super();
+    }
+
+	public List<Converter> getConverterList() {
+		return converterList;
+	}
+
+	public List<MimeType> getMimeTypeList() {
+		if (mimeTypeList == null) {
+			mimeTypeList = new ArrayList<MimeType>();
+			mimeTypeList.add(RXN_TYPE);
+		}
+		return mimeTypeList;
+	}
+	
+}

src/main/java/org/xmlcml/cml/converters/reaction/ReactionTransformer.java

+package org.xmlcml.cml.converters.reaction;
+
+import static org.xmlcml.cml.base.CMLConstants.CML_XPATH;
+
+import static org.xmlcml.euclid.EuclidConstants.S_COMMA;
+import static org.xmlcml.euclid.EuclidConstants.S_EMPTY;
+import static org.xmlcml.euclid.EuclidConstants.S_SPACE;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import nu.xom.Attribute;
+import nu.xom.Nodes;
+
+import org.apache.log4j.Logger;
+import org.xmlcml.cml.base.CMLElement;
+import org.xmlcml.cml.base.CMLElements;
+import org.xmlcml.cml.converters.AbstractConverter;
+import org.xmlcml.cml.element.CMLConditionList;
+import org.xmlcml.cml.element.CMLLabel;
+import org.xmlcml.cml.element.CMLMolecule;
+import org.xmlcml.cml.element.CMLParameter;
+import org.xmlcml.cml.element.CMLProduct;
+import org.xmlcml.cml.element.CMLProductList;
+import org.xmlcml.cml.element.CMLProperty;
+import org.xmlcml.cml.element.CMLPropertyList;
+import org.xmlcml.cml.element.CMLReactant;
+import org.xmlcml.cml.element.CMLReactantList;
+import org.xmlcml.cml.element.CMLReaction;
+import org.xmlcml.cml.element.CMLScalar;
+import org.xmlcml.cml.element.CMLSubstance;
+import org.xmlcml.cml.element.CMLSubstanceList;
+import org.xmlcml.cml.units.Pressure;
+import org.xmlcml.cml.units.Quantity;
+import org.xmlcml.cml.units.Temperature;
+import org.xmlcml.cml.units.Time;
+import org.xmlcml.euclid.EuclidRuntimeException;
+import org.xmlcml.euclid.Real2Range;
+/**
+ * @author pm286
+ *
+ */
+public class ReactionTransformer {
+	
+	private static final Logger LOG = Logger.getLogger(ReactionTransformer.class);
+	
+	private CMLReaction reaction;
+	private CMLElement scopeElement;
+	private CMLConditionList conditionList;
+	private CMLPropertyList propertyList;
+	private CMLSubstanceList substanceList;
+	private CMLReactantList reactantList;
+	private CMLProductList productList;
+
+	/** constructor
+	 */
+	public ReactionTransformer() {
+	}
+	
+	void processAfterParsing() {
+		conditionList = null;
+		substanceList = null;
+		reactantList = new CMLReactantList();
+		reaction.addReactantList(reactantList);
+		addMoleculeRefsToReactants(reactantList);
+		
+		productList = new CMLProductList();
+		reaction.addProductList(productList);
+		addMoleculeRefsToProducts(productList);
+		this.processReactionStepArrowsAndText();
+	}
+	/**
+	 * @param parent
+	 * @param reactionStepArrows
+	 * @throws EuclidRuntimeException
+	 * @throws NumberFormatException
+	 * @throws RuntimeException
+	 */
+	void processReactionStepArrowsAndText() {
+		// will use attributes on reaction later
+//		process(parent);
+//		String reactionStepArrows = reaction.getAttributeValue("ReactionStepArrows", CDX_NAMESPACE);
+		String reactionStepArrows = reaction.getAttributeValue("ReactionStepArrows");
+		if (reactionStepArrows != null) {
+			reactionStepArrows = reactionStepArrows.trim();
+			if (reactionStepArrows.indexOf(S_SPACE) != -1) {
+				LOG.debug("Cannot yet deal with multiple reaction step arrows");
+			} else {
+				Nodes nodes = scopeElement.query("./cml:scalar[@id='"+reactionStepArrows+"']", CML_XPATH);
+				if (nodes.size() == 1) {
+					CMLScalar arrow = (CMLScalar) nodes.get(0);
+					// FIXME
+					Real2Range boundingBox = null;
+//					Real2Range boundingBox = ChemDrawConverter.getNormalizedBoundingBox(arrow);
+					if (boundingBox == null) {
+						
+						LOG.error("null boundingBox");
+						throw new RuntimeException("NOT YET IMPLEMENTED");
+					} else {
+//						Nodes labelNodes = scopeElement.query("./cml:label", CML_XPATH);
+//						List<CMLLabel> labels = ChemDrawConverter.getVerticalLabels(
+//								scopeElement, labelNodes, boundingBox, 50, -50,
+//								MIN_REACTION_LABEL_FONT_SIZE,
+//								MAX_REACTION_LABEL_FONT_SIZE
+//								);
+						List<CMLLabel> labels = null;
+						if (true) throw new RuntimeException("FIXME labels");
+//						labels = ChemDrawConverter.sortLabelsByY(labels);
+						for (CMLLabel label : labels) {
+		//							LOG.debug("L "+label.getCMLValue());
+							// conditions?
+							// DCM, 0{{169}}C, 0.5h 
+							addTextSplitAtCommas(label.getCMLValue(), reaction);
+							label.detach();
+						}
+					}
+					arrow.detach();
+				} else {
+					LOG.error("Cannot find graphic arrow");
+				}
+			}
+		} else {
+			LOG.info("no reactionStepArrows");
+		}
+	}
+	
+	/**
+	 * @param text
+	 * @param reaction
+	 * @throws RuntimeException
+	 */
+	private void addTextSplitAtCommas(String value, CMLReaction reaction) {
+		this.reaction = reaction;
+		if (value != null && !value.trim().equals(S_EMPTY)) {
+			// assume commas separate info
+			String[] vv = value.split(S_COMMA);
+			for (String v : vv) {
+				v = v.trim();
+				// the order of these may be heuristic
+				if (addSolvent(v)) {
+					continue;
+				}
+				if (addTime(v)) {
+					continue;
+				}
+				if (addPressure(v)) {
+					continue;
+				}
+				if (addReagent(v)) {
+					continue;
+				}
+				if (addTemperature(v)) {
+					continue;
+				}
+				if (addYield(v)) {
+					continue;
+				}
+				ensureConditionList();
+				CMLParameter parameter = new CMLParameter();
+				parameter.setDictRef("cml:reactionCondition");
+				CMLScalar scalar = new CMLScalar();
+				conditionList.appendChild(parameter);
+				parameter.addScalar(scalar);
+				scalar.setValue(v);
+			}
+		}
+	}
+	private void ensureConditionList() {
+		if (conditionList == null) {
+			conditionList = new CMLConditionList();
+			reaction.addConditionList(conditionList);
+		}
+	}
+	
+	private void ensurePropertyList() {
+		if (propertyList == null) {
+			propertyList = new CMLPropertyList();
+			reaction.addPropertyList(propertyList);
+		}
+	}
+	
+	private void ensureSubstanceList() {
+		if (substanceList == null) {
+			substanceList = new CMLSubstanceList();
+			reaction.addSubstanceList(substanceList);
+		}
+	}
+	
+	private boolean addReagent(String s) {
+		boolean isReagent = false;
+		String reag = reagentMap.get(s.toLowerCase());
+		if (reag != null) {
+			CMLReactant reagent = new CMLReactant();
+			reagent.addAttribute(new Attribute("title", reag));
+			reagent.setRole("cml:reagent");
+			reagent.setDictRef("cmlreag:"+s);
+			reaction.addReactant(reagent);
+			isReagent = true;
+		}
+		return isReagent;
+	}
+
+	static Pattern yieldPattern = Pattern.compile("(\\d+(\\.\\d+)?) *\\%");
+	private boolean addYield(String s) {
+		Matcher matcher = yieldPattern.matcher(s);
+		boolean isYield = matcher.matches();
+		if (isYield) {
+			CMLProperty yield = new CMLProperty();
+			yield.addAttribute(new Attribute("title", "yield"));
+			yield.setDictRef("cml:"+"yield");
+			CMLScalar scalar = new CMLScalar();
+			scalar.setValue(new Double(matcher.group(1)));
+			scalar.setUnits("units:percent");
+			yield.addScalar(scalar);
+			yield.setRole("yield");
+			ensurePropertyList();
+			propertyList.appendChild(yield);
+		}
+		return isYield;
+	}
+
+	private boolean addSolvent(String s) {
+		boolean isSolv = false;
+		String solv = solventMap.get(s.toLowerCase());
+		if (solv != null) {
+			ensureSubstanceList();
+			CMLSubstance solvent = new CMLSubstance();
+			solvent.addAttribute(new Attribute("title", solv));
+			solvent.setRole("cml:solvent");
+			solvent.setDictRef("cmlrepo:"+s);
+			substanceList.addSubstance(solvent);
+			isSolv = true;
+		}
+		return isSolv;
+	}
+
+	/**
+	 * @param v
+	 * @param parameter
+	 * @param scalar
+	 * @return time
+	 * @throws RuntimeException
+	 */
+	private boolean addTime(String v) {
+		boolean foundTime = false;
+		Quantity t = Time.getTime(v);
+		if (t != null) {
+			CMLParameter parameter = new CMLParameter();
+			CMLScalar scalar = new CMLScalar();
+			scalar.setValue(t.getValue());
+			scalar.setUnits("units:"+t.getUnits().getId());
+			parameter.setRole("duration");
+			parameter.addScalar(scalar);
+			ensureConditionList();
+			conditionList.appendChild(parameter);
+			foundTime = true;
+		}
+		return foundTime;
+	}
+
+	/**
+	 * @param v
+	 * @param parameter
+	 * @param scalar
+	 * @return pressure
+	 * @throws RuntimeException
+	 */
+	private boolean addPressure(String v) {
+		boolean foundPressure = false;
+		Quantity p = Pressure.getPressure(v);
+		if (p != null) {
+			CMLParameter parameter = new CMLParameter();
+			CMLScalar scalar = new CMLScalar();
+			scalar.setValue(p.getValue());
+			scalar.setUnits("units:"+p.getUnits().getId());
+			parameter.setRole("pressure");
+			parameter.addScalar(scalar);
+			ensureConditionList();
+			conditionList.appendChild(parameter);
+			foundPressure = true;
+		}
+		return foundPressure;
+	}
+
+	/**
+	 * @param v
+	 * @param parameter
+	 * @param scalar
+	 * @return temperature
+	 * @throws RuntimeException
+	 */
+	private boolean addTemperature(String v) {
+		boolean foundTemp = false;
+		Temperature t = Temperature.getTemperature(v);
+		if (t != null) {
+			CMLParameter parameter = new CMLParameter();
+			CMLScalar scalar = new CMLScalar();
+			scalar.setValue(t.getValue());
+			scalar.setUnits("units:"+t.getUnits().getId());
+			parameter.setRole("temperature");
+			parameter.addScalar(scalar);
+			ensureConditionList();
+			conditionList.appendChild(parameter);
+			foundTemp = true;
+		}
+		return foundTemp;
+	}
+
+	/**
+	 * @param element
+	 * @param reactantList
+	 * @param reactantS
+	 * @throws RuntimeException
+	 */
+	private void addMoleculeRefsToReactants(CMLReactantList reactantList) {
+//		String reactantS = reaction.getAttributeValue("ReactionStepReactants", CDX_NAMESPACE);
+		String reactantS = reaction.getAttributeValue("ReactionStepReactants");
+		if (reactantS == null) {
+			throw new RuntimeException("Null reactant String");
+		}
+		String[] reactantIds = reactantS.split(S_SPACE);
+		for (String id : reactantIds) {
+			Nodes nodes = findNodesWithIds(scopeElement, id);
+			if (nodes.size() == 0) {
+				continue;
+			}
+			if (nodes.get(0) instanceof CMLMolecule) {
+				CMLMolecule refMolecule = new CMLMolecule();
+				refMolecule.setRef(id);
+				CMLReactant reactant = new CMLReactant();
+				reactantList.addReactant(reactant);
+				reactant.addMolecule(refMolecule);
+				addRoleAndLabel((CMLMolecule) nodes.get(0), refMolecule);
+			} else if (nodes.get(0) instanceof CMLLabel) {
+				LOG.error("Cannot use label as reactant: "+id);
+			} else {
+				throw new RuntimeException("unexpected reactant: "+id);
+			}
+		}
+	}
+
+	/**
+	 * @param element
+	 * @param id
+	 * @return nodes
+	 */
+	private Nodes findNodesWithIds(CMLElement element, String id) {
+		Nodes nodes = element.query("//*[@id='"+id+"']");
+		if (nodes.size() ==0) {
+			LOG.error("******************Cannot find molecule or label: "+id);
+		}
+		return nodes;
+	}
+
+	/**
+	 * @param nodes
+	 * @param refMolecule
+	 * @throws RuntimeException
+	 */
+	private void addRoleAndLabel(CMLMolecule molecule, CMLMolecule refMolecule) {
+		if ("cdx:fragment".equals(molecule.getRole())) {
+			refMolecule.setRole("reagent");
+		}
+		CMLElements<CMLLabel> labelList = molecule.getLabelElements();
+		if (labelList.size() > 0) {
+			CMLLabel label = new CMLLabel(labelList.get(0));
+			label.removeAttribute("id");
+			refMolecule.addLabel(label);
+		}
+	}
+	
+	/**
+	 * @param element
+	 * @param productList
+	 * @param productS
+	 * @throws RuntimeException
+	 */
+	private void addMoleculeRefsToProducts(CMLProductList productList) {
+//		String productS = reaction.getAttributeValue("ReactionStepProducts", CDX_NAMESPACE);
+		String productS = reaction.getAttributeValue("ReactionStepProducts");
+		if (productS == null) {
+			throw new RuntimeException("Null product String");
+		}
+		String[] productIds = productS.split(S_SPACE);
+		for (String id : productIds) {
+			Nodes nodes = findNodesWithIds(scopeElement, id);
+			if (nodes.size() == 0) {
+				continue;
+			}
+			if (nodes.get(0) instanceof CMLMolecule) {
+				CMLMolecule refMolecule = new CMLMolecule();
+				refMolecule.setRef(id);
+				CMLProduct product = new CMLProduct();
+				productList.addProduct(product);
+				product.addMolecule(refMolecule);
+				addRoleAndLabel((CMLMolecule) nodes.get(0), refMolecule);
+			} else if (nodes.get(0) instanceof CMLLabel) {
+				LOG.warn("Cannot use label as product: "+id);
+			} else {
+				throw new RuntimeException("unexpected product: "+id);
+			}
+		}
+	}
+	
+	final static Map<String, String> reagentMap;
+	static final String[] reagents = {
+		"(-)DET",
+		"18-crown-6",
+		"4-pentenoyl chloride",
+		"Ac2O",
+		"Al2O3",
+		"allylstannane",
+		"allyltributyltin",
+		"BF3OEt2",
+		"BF3{{149}}OEt2",
+		"BnBr",
+		"(C6H5)3P=CHO2CH3",
+		"(COCl)2",
+		"Cp2TiMe2",
+		"D-(-)DIPT",
+		"DABCO",
+		"DIBAL-H",
+		"DMAP",
+		"Et3N",
+		"Fe(CO)5",
+		"Fe2(CO)9",
+		"H2",
+		"(H2C=O)n",
+		"HFpyr",
+		"HF{{149}}pyr",
+		"(iBu)3Al",
+		"imidazole",
+		"iPr2NH",
+		"iPr2NEt",
+		"K2CO3",
+		"KOH",
+		"Lindlar catalyst",
+		"Li",
+		"MEMCl",
+		"Na2CO3",
+		"NaBH3CN",
+		"NaH",
+		"Naphthalene",
+		"nBu4NI",
+		"nBuLi",
+		"NEt3",
+		"p-NO2C6H4CHO",
+		"OsO4",
+		"Pd/C",
+		"PhCHO",
+		"PhNH2",
+		"(Ph)3PRuCl2",
+		"Quinoline",
+		"(Pd/CaCO3/PbO)",
+		"(Ph3P)3RuCl2",
+		"SO2Cl2",
+		"TBSCl",
+		"TBSOTf",
+		"tBuOK",
+		"tBuOOH",
+		"Ti(OiPr)4",
+		"TMSOTf",
+		"p-TsOH",
+		"VO(acac)2",
+		
+	};
+	
+	final static Map<String, String> solventMap;
+	static final String[] solvents = {
+		"benzene",
+		"Celite",
+		"CH2Cl2",
+		"CHCl3",
+		"DCM",
+		"DMF",
+		"DMSO",
+		"Et2O",
+		"EtOAc",
+		"MeCN",
+		"MeOH",
+		"petrol",
+		"PhH",
+		"Pyr",
+		"THF",
+		"toluene"
+	};
+	
+	static final Pattern[] temps = {
+		Pattern.compile("(\\-?\\d+(\\.\\d+)?) *C"),
+	};
+	static {
+		solventMap = new HashMap<String, String>();
+		for (String s : solvents) {
+			solventMap.put(s.toLowerCase(), s);
+		}
+		reagentMap = new HashMap<String, String>();
+		for (String s : reagents) {
+			reagentMap.put(s.toLowerCase(), s);
+		}
+	}
+	/**
+	 * @return the reaction
+	 */
+	public CMLReaction getReaction() {
+		return reaction;
+	};
+}
+
+
+

src/main/java/org/xmlcml/cml/converters/reaction/package-info.java

+/** 
+Reaction module
+*/
+package org.xmlcml.cml.converters.reaction;

src/main/java/org/xmlcml/cml/converters/reaction/properties/CMLRDFObject.java

+package org.xmlcml.cml.converters.reaction.properties;
+
+
+import nu.xom.Attribute;
+
+import org.apache.log4j.Logger;
+import org.xmlcml.cml.base.CMLConstants;
+import org.xmlcml.cml.base.CMLElement;
+import org.xmlcml.cml.converters.rdf.rdf.RDFDescription;
+import org.xmlcml.cml.converters.rdf.rdf.RDFRdf;
+import org.xmlcml.cml.converters.rdf.rdf.RDFTriple;
+import org.xmlcml.cml.converters.reaction.properties.MMReConstants.Predicate;
+import org.xmlcml.cml.converters.reaction.properties.MMReConstants.Unit;
+import org.xmlcml.cml.element.CMLAction;
+import org.xmlcml.cml.element.CMLAmount;
+import org.xmlcml.cml.element.CMLLabel;
+import org.xmlcml.cml.element.CMLName;
+import org.xmlcml.cml.element.CMLParameter;
+import org.xmlcml.cml.element.CMLProduct;
+import org.xmlcml.cml.element.CMLProperty;
+import org.xmlcml.cml.element.CMLReactant;
+import org.xmlcml.cml.element.CMLReaction;
+import org.xmlcml.cml.element.CMLScalar;
+import org.xmlcml.cml.element.CMLSubstance;
+
+public class CMLRDFObject {
+	private static Logger LOG = Logger.getLogger(CMLRDFObject.class);
+	
+	private RDFRdf rdf;
+	
+	public CMLRDFObject(RDFRdf rdf) {
+		this.rdf = rdf;
+	}
+	
+/**
+		HAS_MASS("hasGram"),
+		HAS_VOL("hasVol"),
+		HAS_MOLAR_AMOUNT("hasMol"),
+		HAS_PERCENT("hasPercent"),
+		
+		HAS_AMOUNT("hasAmount"),
+		HAS_COLOR("hasColor"),
+		HAS_CHROMATOGRAPHY("hasChromatography"),
+		IS_EXTRACTED_BY("isExtractedBy"),
+		HAS_FILTER_PHRASE("hasFilter-Phrase"),
+		IS_FILTERED_BY("isFilteredBy"),
+		HAS_NAME("hasName"),
+		HAS_NUMBER("hasNumber"),
+		HAS_PREPARATION("hasPreparation"),
+		HAS_PRODUCT("hasProduct"),
+		IS_CONCENTRATED_BY("isConcentrateedBy"),
+		IS_PURIFIED_BY("isPurifiedBy"),
+		IS_WASHED_BY("isWashedBy"),
+		HAS_REACTANT("hasReactant"),
+		HAS_ROLE("hasRole"),
+		HAS_STATE("hasState"),
+		HAS_SUBSTANCE("hasSubstance"),
+		HAS_PRESSURE("hasPressure"),
+		HAS_TEMP("hasTemp"),
+		HAS_TIME("hasTime"),
+		HAS_UNIT("hasUnit"),
+		HAS_VALUE("hasValue"),
+ */	
+	
+	public void expandDescription(RDFDescription description, CMLElement element) {
+		if (element == null) {
+			throw new RuntimeException("NULL");
+		}
+		element.setId(description.getId());
+		for (RDFTriple triple : description.getTripleList()) {
+			expandTriple(triple, element);
+		}
+	}
+
+	/**
+	 * triple can either have resource pointer or content
+	 * @param element
+	 * @param triple
+	 */
+	public void expandTriple(RDFTriple triple, CMLElement element) {
+		RDFDescription resourceDescription = triple.getResourceDescription(rdf);
+		CMLElement newElement = createCMLElement(triple, element);
+		if (newElement == null) {
+			LOG.trace("null element "+triple.getLocalName());
+		} else {
+			element.appendChild(newElement);
+			String id = triple.getResourceId();
+			if (id != null) {
+				newElement.addAttribute(new Attribute("ref", id));
+			}
+			String content = triple.getContent();
+			if (resourceDescription != null) {
+				expandDescription(resourceDescription, newElement);
+			} else if (content != null) {
+				// leaf node
+				newElement.appendChild(content);
+				String dataType = triple.getDatatype();
+				if (dataType != null) {
+					newElement.addAttribute(new Attribute("dataType", dataType));
+				}
+				removeTemporaryRefAttribute(newElement);
+			} else if (id != null) {
+				// leave an empty pointer
+			} else {
+				// leave empty element
+				LOG.warn("No resource pointer/Id or content "+triple);
+			}
+			// remove ref from parent
+		}
+		removeTemporaryRefAttribute(element);
+	}
+
+	private void removeTemporaryRefAttribute(CMLElement element) {
+		String ref = element.getAttributeValue("ref");
+		if (ref != null) {
+			element.setId(ref);
+			element.removeAttribute("ref");
+		}
+	}
+	
+	public CMLElement createCMLElement(RDFTriple triple, CMLElement element) {
+		CMLElement newElement = null;
+		String localName = triple.getLocalName();
+		String content = triple.getContent();
+		Predicate predicate = Predicate.getPredicate(localName);
+		if (predicate == null) {
+			throw new RuntimeException("Unknown predicate: "+localName);
+
+		} else if (
+			predicate.equals(Predicate.HAS_MASS) ||
+			predicate.equals(Predicate.HAS_VOL) ||
+			predicate.equals(Predicate.HAS_MOLAR_AMOUNT) ||
+			predicate.equals(Predicate.HAS_PERCENT)) {
+			newElement = new CMLScalar();
+			if (predicate.dictRef != null) {
+				newElement.addAttribute(new Attribute("dictRef", predicate.dictRef));
+			}
+			newElement.addAttribute(new Attribute("dataType", CMLConstants.XSD_DOUBLE));
+			
+		} else if (predicate.equals(Predicate.HAS_AMOUNT)) {
+			newElement = new CMLAmount();
+			
+		} else if (
+			predicate.equals(Predicate.HAS_COLOR) ||
+			predicate.equals(Predicate.HAS_STATE)) {
+			newElement = new CMLProperty();
+			if (predicate.dictRef != null) {
+				newElement.addAttribute(new Attribute("dictRef", predicate.dictRef));
+			}
+		} else if (
+				predicate.equals(Predicate.IS_CONCENTRATED_BY) ||
+				predicate.equals(Predicate.IS_PURIFIED_BY) ||
+				predicate.equals(Predicate.IS_WASHED_BY) ||
+				predicate.equals(Predicate.HAS_CHROMATOGRAPHY) ||
+				predicate.equals(Predicate.IS_EXTRACTED_BY) ||
+				predicate.equals(Predicate.HAS_FILTER_PHRASE) ||
+				predicate.equals(Predicate.IS_FILTERED_BY)) {
+			newElement = new CMLAction();
+			if (predicate.dictRef != null) {
+				newElement.addAttribute(new Attribute("role", predicate.dictRef));
+			}
+		} else if (predicate.equals(Predicate.HAS_NAME)) {
+			newElement = new CMLName();
+		} else if (predicate.equals(Predicate.HAS_NUMBER)) {
+			newElement = new CMLLabel();
+			if (predicate.dictRef != null) {
+				newElement.addAttribute(new Attribute("role", predicate.dictRef));
+			}
+		} else if (predicate.equals(Predicate.HAS_PREPARATION)) {
+			newElement = new CMLReaction();
+		} else if (predicate.equals(Predicate.HAS_PRODUCT)) {
+			newElement = new CMLProduct();
+		} else if (predicate.equals(Predicate.HAS_REACTANT)) {
+			newElement = new CMLReactant();
+		} else if (predicate.equals(Predicate.HAS_ROLE)) {
+			element.addAttribute(new Attribute("role", content));
+		} else if (predicate.equals(Predicate.HAS_SUBSTANCE)) {
+			newElement = new CMLSubstance();
+		} else if (
+				predicate.equals(Predicate.HAS_PRESSURE) ||
+				predicate.equals(Predicate.HAS_TIME) ||
+				predicate.equals(Predicate.HAS_TEMP)
+				) {
+			newElement = new CMLParameter();
+			if (predicate.dictRef != null) {
+				newElement.addAttribute(new Attribute("dictRef", predicate.dictRef));
+			}
+			newElement.addAttribute(new Attribute("dataType", CMLConstants.XSD_DOUBLE));
+
+		} else if (predicate.equals(Predicate.HAS_UNIT)) {
+			content = RDFRdf.translateChars(content);
+			Unit unit = MMReConstants.UNIT_MAP.get(content);
+			if (unit == null) {
+				throw new RuntimeException("unknown unit: "+content);
+			}
+			element.addAttribute(new Attribute(MMReConstants.UNIT_ATTNAME, unit.value));
+
+		} else if (predicate.equals(Predicate.HAS_VALUE)) {
+			element.addAttribute(new Attribute("value", content));
+		} else {
+			throw new RuntimeException("unknown predicate "+predicate);
+		}
+		return newElement;
+	}
+}

src/main/java/org/xmlcml/cml/converters/reaction/properties/MMReConstants.java

+package org.xmlcml.cml.converters.reaction.properties;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import nu.xom.XPathContext;
+
+import org.xmlcml.cml.converters.rdf.rdf.RDFConstants;
+
+public class MMReConstants {
+
+	public final static String MICRO = "&#956;";
+	public final static String UNIT_NS = "http://www.xml-cml.org/units";
+	public final static String UNIT_NS_PREFIX = "unit";
+	public final static String UNIT_ATTNAME = "units";
+	
+	public enum Unit {
+		CELSIUS("unit:celsius"),
+		
+		MILLIGRAM("unit:mg"),
+		GRAM("unit:gram"),
+		
+		MILLILITRE("unit:ml"),
+		MICROLITRE("unit:microl"),
+		
+		MICROMOL("unit:micromol"),
+		MMOL("unit:mmol"),
+		MOL("unit:mol"),
+		
+		PERCENT("unit:percent"),
+		
+		MIN("unit:min"),
+		HOUR("unit:hour"),
+		UNKNOWN("unit:unknown"),
+		;
+		public String value;
+		private Unit(String s) {
+			this.value = s;
+		}
+		public static Unit getUnit(String v) {
+			Unit p = null;
+			for (Unit pp : Unit.values()) {
+				if (pp.value.equals(v)) {
+					p = pp;
+					break;
+				}
+			}
+			return p;
+		}
+	}
+
+	public enum DictRef {
+		COLOR("cml:color"),
+		PRESSURE("cml:pressure"),
+		TEMPERATURE("cml:temp"),
+		TIME("cml:time")
+		;
+		public String value;
+		private DictRef(String s) {
+			this.value = s;
+		}
+	}
+
+	public enum Predicate {
+		HAS_MASS("hasGram", "cml:mass"),
+		HAS_VOL("hasVol", "cml:volume"),
+		HAS_MOLAR_AMOUNT("hasMol", "cml:molarAmount"),
+		HAS_PERCENT("hasPercent", "cml:percent"),
+		
+		HAS_AMOUNT("hasAmount"),
+		HAS_COLOR("hasColor", "cml:color"),
+		HAS_CHROMATOGRAPHY("hasChromatography", "cml:chromatography"),
+		IS_EXTRACTED_BY("isExtractedBy", "cml:extraction"),
+		HAS_FILTER_PHRASE("hasFilter-Phrase", "cml:filter"),
+		IS_FILTERED_BY("isFilteredBy", "cml:filter"),
+		HAS_NAME("hasName"),
+		HAS_NUMBER("hasNumber", "cml:serialNumber"),
+		HAS_PREPARATION("hasPreparation"),
+		HAS_PRODUCT("hasProduct"),
+		IS_CONCENTRATED_BY("isConcentrateedBy", "cml:concentrated"),
+		IS_PURIFIED_BY("isPurifiedBy", "cml:purified"),
+		IS_WASHED_BY("isWashedBy", "cml:washed"),
+		HAS_REACTANT("hasReactant"),
+		HAS_ROLE("hasRole"),
+		HAS_STATE("hasState", "cml:state"),
+		HAS_SUBSTANCE("hasSubstance"),
+		HAS_PRESSURE("hasPressure", "cml:pressure"),
+		HAS_TEMP("hasTemp", "cml:temp"),
+		HAS_TIME("hasTime", "cml:time"),
+		HAS_UNIT("hasUnit"),
+		HAS_VALUE("hasValue"),
+		;
+		public final String value;
+		public final String dictRef;
+		private Predicate(String s) {
+			this.value = s;
+			this.dictRef = null;
+		}
+		private Predicate(String s, String dictRef) {
+			this.value = s;
+			this.dictRef = dictRef;
+		}
+		public static Predicate getPredicate(String v) {
+			Predicate p = null;
+			for (Predicate pp : Predicate.values()) {
+				if (pp.value.equals(v)) {
+					p = pp;
+					break;
+				}
+			}
+			return p;
+		}
+		public boolean isAmount() {
+			return (this.equals(HAS_MASS) || 
+					this.equals(HAS_MOLAR_AMOUNT) ||
+					this.equals(HAS_VOL) ||
+				this.equals(HAS_PERCENT));
+		}
+	}
+	
+	public final static Map<Predicate, Set<Unit>> UNIT_TYPE_MAP = new HashMap<Predicate, Set<Unit>>();
+	static {
+		Set<Unit> unitSet = null;
+		unitSet = new HashSet<Unit>();
+		unitSet.add(Unit.GRAM);
+		UNIT_TYPE_MAP.put(Predicate.HAS_MASS, unitSet);
+		unitSet = new HashSet<Unit>();
+		unitSet.add(Unit.MILLILITRE);
+		UNIT_TYPE_MAP.put(Predicate.HAS_VOL, unitSet);
+		unitSet = new HashSet<Unit>();
+		unitSet.add(Unit.MOL);
+		UNIT_TYPE_MAP.put(Predicate.HAS_MOLAR_AMOUNT, unitSet);
+		unitSet = new HashSet<Unit>();
+		unitSet.add(Unit.PERCENT);
+		UNIT_TYPE_MAP.put(Predicate.HAS_PERCENT, unitSet);
+	}
+	
+	public final static Map<String, Unit> UNIT_MAP = new HashMap<String, Unit>();
+	static {
+		UNIT_MAP.put("ml", Unit.MILLILITRE);
+		UNIT_MAP.put("mL", Unit.MILLILITRE);
+		UNIT_MAP.put("�L", Unit.MICROLITRE);
+		UNIT_MAP.put(MICRO+"L", Unit.MICROLITRE);
+		UNIT_MAP.put(MICRO+"l", Unit.MICROLITRE);
+		
+		UNIT_MAP.put("mg", Unit.MILLIGRAM);
+		UNIT_MAP.put("g", Unit.GRAM);
+		UNIT_MAP.put("gram", Unit.GRAM);
+		
+		UNIT_MAP.put("hr", Unit.HOUR);
+		UNIT_MAP.put("hour", Unit.HOUR);
+		UNIT_MAP.put("hours", Unit.HOUR);
+		
+		UNIT_MAP.put("mmol", Unit.MMOL);
+		UNIT_MAP.put("mol", Unit.MOL);
+		UNIT_MAP.put("?mol", Unit.MICROMOL);
+		UNIT_MAP.put("&#956;mol", Unit.MICROMOL);
+		
+		UNIT_MAP.put("Celsius", Unit.CELSIUS);
+		UNIT_MAP.put("celsius", Unit.CELSIUS);
+		UNIT_MAP.put("%", Unit.PERCENT);
+	}
+	
+	
+	public final static String MMRE_NS = "http://www.polymerinformatics.com/RecipeRepository.owl#";
+	public final static XPathContext MMRE_XPATH= new XPathContext("mmre", MMRE_NS);
+	public final static XPathContext RDF_MMRE_XPATH = new XPathContext("rdf", RDFConstants.RDF_NS);
+	static {
+		RDF_MMRE_XPATH.addNamespace("mmre", MMRE_NS);
+	};
+	
+
+}

src/main/java/org/xmlcml/cml/converters/reaction/properties/package-info.java

+/** 
+Reaction properties
+May be obsolete
+*/
+package org.xmlcml.cml.converters.reaction.properties;

src/main/resources/META-INF/jumbo-converters

+org.xmlcml.cml.converters.reaction.ReactionConverters

src/test/resources/org/xmlcml/cml/converters/reaction/cdx/US20090039313A1-20090212-C00003.CDX

Binary file added.

src/test/resources/org/xmlcml/cml/converters/reaction/cdx/US20090039313A1-20090212-C00004.CDX

Binary file added.

src/test/resources/org/xmlcml/cml/converters/reaction/cdx/US20090039313A1-20090212-C00005.CDX

Binary file added.

src/test/resources/org/xmlcml/cml/converters/reaction/mdl/US20090039313A1-20090212-C00003.MOL

+00023001.cdx
+  ChemDraw01200918142D
+
+ 70 72  0  0  0  0  0  0  0  0999 V2000
+   -1.1942    5.1568    0.0000 Mg  0  0  0  0  0  0  0  0  0  0  0  0
+    0.9705    4.7252    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+    0.9705    3.9002    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+    1.6849    3.4877    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+    2.3994    3.9002    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+    2.3994    4.7252    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+    1.6849    5.1377    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+    0.2560    5.1377    0.0000 Si  0  0  0  0  0  0  0  0  0  0  0  0
+   -0.1565    4.4232    0.0000 O   0  0  0  0  0  0  0  0  0  0  0  0
+   -0.9815    4.4232    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+   -0.4585    5.5502    0.0000 O   0  0  0  0  0  0  0  0  0  0  0  0
+   -1.1729    5.1377    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+    0.6685    5.8522    0.0000 O   0  0  0  0  0  0  0  0  0  0  0  0
+    0.2560    6.5666    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+   -3.4753    3.0544    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+   -3.4753    3.8794    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+   -4.1898    4.2919    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+   -4.9042    3.8794    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+   -4.9042    3.0544    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+   -4.1898    2.6419    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+   -5.6187    4.2919    0.0000 H   0  0  0  0  0  0  0  0  0  0  0  0
+   -5.6187    2.6419    0.0000 H   0  0  0  0  0  0  0  0  0  0  0  0
+   -2.7608    2.6419    0.0000 H   0  0  0  0  0  0  0  0  0  0  0  0
+   -4.1898    1.8169    0.0000 Br  0  0  0  0  0  0  0  0  0  0  0  0
+   -2.7608    4.2919    0.0000 H   0  0  0  0  0  0  0  0  0  0  0  0
+   -4.9042    7.1794    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+   -4.9042    6.3544    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+   -4.1898    5.9419    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+   -3.4753    6.3544    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+   -3.4753    7.1794    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+   -4.1898    7.5919    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+   -4.1898    8.4169    0.0000 H   0  0  0  0  0  0  0  0  0  0  0  0
+   -2.7608    7.5919    0.0000 H   0  0  0  0  0  0  0  0  0  0  0  0
+   -2.7608    5.9419    0.0000 H   0  0  0  0  0  0  0  0  0  0  0  0
+   -4.1898    5.1169    0.0000 O   0  0  0  0  0  0  0  0  0  0  0  0
+   -5.6187    7.5919    0.0000 H   0  0  0  0  0  0  0  0  0  0  0  0
+   -5.6187    5.9419    0.0000 H   0  0  0  0  0  0  0  0  0  0  0  0
+    4.4769   -6.1076    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+    4.4769   -5.2826    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+    3.7624   -4.8701    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+    3.0480   -5.2826    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+    3.0480   -6.1076    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+    3.7624   -6.5201    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+    2.3335   -4.8701    0.0000 H   0  0  0  0  0  0  0  0  0  0  0  0
+    2.3335   -6.5201    0.0000 H   0  0  0  0  0  0  0  0  0  0  0  0
+    5.1914   -6.5201    0.0000 H   0  0  0  0  0  0  0  0  0  0  0  0
+    3.7624   -7.3451    0.0000 Si  0  0  0  0  0  0  0  0  0  0  0  0
+    5.1914   -4.8701    0.0000 H   0  0  0  0  0  0  0  0  0  0  0  0
+    3.0480   -1.9826    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+    3.0480   -2.8076    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+    3.7624   -3.2201    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+    4.4769   -2.8076    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+    4.4769   -1.9826    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+    3.7624   -1.5701    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+    3.7624   -0.7451    0.0000 H   0  0  0  0  0  0  0  0  0  0  0  0
+    5.1914   -1.5701    0.0000 H   0  0  0  0  0  0  0  0  0  0  0  0
+    5.1914   -3.2201    0.0000 H   0  0  0  0  0  0  0  0  0  0  0  0
+    3.7624   -4.0451    0.0000 O   0  0  0  0  0  0  0  0  0  0  0  0
+    2.3335   -1.5701    0.0000 H   0  0  0  0  0  0  0  0  0  0  0  0
+    2.3335   -3.2201    0.0000 H   0  0  0  0  0  0  0  0  0  0  0  0
+    3.8582   -7.4004    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+    3.1437   -6.9879    0.0000 O   0  0  0  0  0  0  0  0  0  0  0  0
+    3.9687   -7.7024    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+    4.3812   -8.4169    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+    5.2062   -8.4169    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+    5.6187   -7.7024    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+    5.2062   -6.9879    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+    4.3812   -6.9879    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+    4.3812   -7.2899    0.0000 O   0  0  0  0  0  0  0  0  0  0  0  0
+    5.0957   -7.7024    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+  2  3  2  0      
+  3  4  1  0      
+  4  5  2  0      
+  5  6  1  0      
+  6  7  2  0      
+  2  7  1  0      
+  2  8  1  0      
+  8  9  1  0      
+  8 11  1  0      
+  8 13  1  0      
+  9 10  1  0      
+ 11 12  1  0      
+ 13 14  1  0      
+ 15 16  2  0      
+ 16 17  1  0      
+ 17 18  2  0      
+ 18 19  1  0      
+ 19 20  2  0      
+ 20 15  1  0      
+ 18 21  1  0      
+ 19 22  1  0      
+ 17 35  1  0      
+ 16 25  1  0      
+ 15 23  1  0      
+ 20 24  1  0      
+ 26 27  1  0      
+ 27 28  2  0      
+ 28 29  1  0      
+ 29 30  2  0      
+ 30 31  1  0      
+ 31 26  2  0      
+ 31 32  1  0      
+ 30 33  1  0      
+ 29 34  1  0      
+ 28 35  1  0      
+ 26 36  1  0      
+ 27 37  1  0      
+ 38 39  2  0      
+ 39 40  1  0      
+ 40 41  2  0      
+ 41 42  1  0      
+ 42 43  2  0      
+ 43 38  1  0      
+ 41 44  1  0      
+ 42 45  1  0      
+ 40 58  1  0      
+ 39 48  1  0      
+ 38 46  1  0      
+ 43 47  1  0      
+ 49 50  1  0      
+ 50 51  2  0      
+ 51 52  1  0      
+ 52 53  2  0      
+ 53 54  1  0      
+ 54 49  2  0      
+ 54 55  1  0      
+ 53 56  1  0      
+ 52 57  1  0      
+ 51 58  1  0      
+ 49 59  1  0      
+ 50 60  1  0      
+ 47 62  1  0      
+ 61 62  1  0      
+ 47 63  1  0      
+ 63 64  2  0      
+ 64 65  1  0      
+ 65 66  2  0      
+ 66 67  1  0      
+ 67 68  2  0      
+ 63 68  1  0      
+ 47 69  1  0      
+ 69 70  1  0      
+M  STY  1   1 SUP
+M  SLB  1   1   1
+M  SAL   1 13   2   3   4   5   6   7   8   9  10  11  12  13  14
+M  SMT   1 PhSi(OMe)3
+M  STY  1   2 SUP
+M  SLB  1   2   2
+M  SAL   2  2  61  62
+M  SBL   2  1  62
+M  SMT   2 MeO
+M  SBV   2 62   -6.3723   10.3437
+M  STY  1   3 SUP
+M  SLB  1   3   3
+M  SAL   3  6  63  64  65  66  67  68
+M  SBL   3  1  64
+M  SMT   3 Ph
+M  SBV   3 64   -5.5473    9.6292
+M  STY  1   4 SUP
+M  SLB  1   4   4
+M  SAL   4  2  69  70
+M  SBL   4  1  71
+M  SMT   4 OMe
+M  SBV   4 71   -5.1348   10.0417
+M  END

src/test/resources/org/xmlcml/cml/converters/reaction/mdl/US20090039313A1-20090212-C00004.MOL

+00024001.cdx
+  ChemDraw01200918162D
+
+ 94 97  0  0  0  0  0  0  0  0999 V2000
+    4.4769   -6.9020    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+    4.4769   -6.0770    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+    3.7624   -5.6645    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+    3.0480   -6.0770    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+    3.0480   -6.9020    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+    3.7624   -7.3145    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+    2.3335   -5.6645    0.0000 H   0  0  0  0  0  0  0  0  0  0  0  0
+    2.3335   -7.3145    0.0000 H   0  0  0  0  0  0  0  0  0  0  0  0
+    5.1914   -7.3145    0.0000 H   0  0  0  0  0  0  0  0  0  0  0  0
+    3.7624   -8.1395    0.0000 Si  0  0  0  0  0  0  0  0  0  0  0  0
+    5.1914   -5.6645    0.0000 H   0  0  0  0  0  0  0  0  0  0  0  0
+    3.0480   -2.7770    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+    3.0480   -3.6020    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+    3.7624   -4.0145    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+    4.4769   -3.6020    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+    4.4769   -2.7770    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+    3.7624   -2.3645    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+    3.7624   -1.5395    0.0000 H   0  0  0  0  0  0  0  0  0  0  0  0
+    5.1914   -2.3645    0.0000 H   0  0  0  0  0  0  0  0  0  0  0  0
+    5.1914   -4.0145    0.0000 H   0  0  0  0  0  0  0  0  0  0  0  0
+    3.7624   -4.8395    0.0000 O   0  0  0  0  0  0  0  0  0  0  0  0
+    2.3335   -2.3645    0.0000 H   0  0  0  0  0  0  0  0  0  0  0  0
+    2.3335   -4.0145    0.0000 H   0  0  0  0  0  0  0  0  0  0  0  0
+    3.8582   -8.1947    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+    3.1437   -7.7822    0.0000 O   0  0  0  0  0  0  0  0  0  0  0  0
+    4.3812   -8.0842    0.0000 O   0  0  0  0  0  0  0  0  0  0  0  0
+    5.0957   -8.4967    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+    3.9687   -8.4967    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+    4.3812   -9.2112    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+    5.2062   -9.2112    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+    5.6187   -8.4967    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+    5.2062   -7.7822    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+    4.3812   -7.7822    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+   -1.8912   -5.5849    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+   -1.8912   -6.4099    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+   -1.1768   -6.8224    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+   -0.4623   -6.4099    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+   -0.4623   -5.5849    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+   -1.1768   -5.1724    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+   -2.6057   -5.1724    0.0000 Si  0  0  0  0  0  0  0  0  0  0  0  0
+   -3.0182   -5.8869    0.0000 O   0  0  0  0  0  0  0  0  0  0  0  0
+   -3.8432   -5.8869    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+   -3.3202   -4.7599    0.0000 O   0  0  0  0  0  0  0  0  0  0  0  0
+   -4.0347   -5.1724    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+   -2.1932   -4.4580    0.0000 O   0  0  0  0  0  0  0  0  0  0  0  0
+   -2.6057   -3.7435    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+   -3.4753    3.8100    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+   -3.4753    4.6350    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+   -4.1898    5.0475    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+   -4.9042    4.6350    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+   -4.9042    3.8100    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+   -4.1898    3.3975    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+   -5.6187    5.0475    0.0000 H   0  0  0  0  0  0  0  0  0  0  0  0
+   -5.6187    3.3975    0.0000 H   0  0  0  0  0  0  0  0  0  0  0  0
+   -2.7608    3.3975    0.0000 H   0  0  0  0  0  0  0  0  0  0  0  0
+   -4.1898    2.5725    0.0000 Br  0  0  0  0  0  0  0  0  0  0  0  0
+   -2.7608    5.0475    0.0000 H   0  0  0  0  0  0  0  0  0  0  0  0
+   -4.9042    7.9350    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+   -4.9042    7.1100    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+   -4.1898    6.6975    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+   -3.4753    7.1100    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+   -3.4753    7.9350    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+   -4.1898    8.3475    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+   -4.1898    9.1725    0.0000 H   0  0  0  0  0  0  0  0  0  0  0  0
+   -2.7608    8.3475    0.0000 H   0  0  0  0  0  0  0  0  0  0  0  0
+   -2.7608    6.6975    0.0000 H   0  0  0  0  0  0  0  0  0  0  0  0
+   -4.1898    5.8725    0.0000 O   0  0  0  0  0  0  0  0  0  0  0  0
+   -5.6187    8.3475    0.0000 H   0  0  0  0  0  0  0  0  0  0  0  0
+   -5.6187    6.6975    0.0000 H   0  0  0  0  0  0  0  0  0  0  0  0
+   -1.2444    5.9125    0.0000 Mg  0  0  0  0  0  0  0  0  0  0  0  0
+    3.6270    3.8487    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+    3.6270    4.6737    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+    2.9125    5.0862    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+    2.1980    4.6737    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+    2.1980    3.8487    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+    2.9125    3.4362    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+    1.4836    5.0862    0.0000 H   0  0  0  0  0  0  0  0  0  0  0  0
+    1.4836    3.4362    0.0000 H   0  0  0  0  0  0  0  0  0  0  0  0
+    4.3415    3.4362    0.0000 H   0  0  0  0  0  0  0  0  0  0  0  0
+    4.3415    5.0862    0.0000 H   0  0  0  0  0  0  0  0  0  0  0  0
+    2.1980    7.9737    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+    2.1980    7.1487    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+    2.9125    6.7362    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+    3.6270    7.1487    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+    3.6270    7.9737    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+    2.9125    8.3862    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+    2.9125    9.2112    0.0000 H   0  0  0  0  0  0  0  0  0  0  0  0
+    4.3415    8.3862    0.0000 H   0  0  0  0  0  0  0  0  0  0  0  0
+    4.3415    6.7362    0.0000 H   0  0  0  0  0  0  0  0  0  0  0  0
+    2.9125    5.9112    0.0000 O   0  0  0  0  0  0  0  0  0  0  0  0
+    1.4836    8.3862    0.0000 H   0  0  0  0  0  0  0  0  0  0  0  0
+    1.4836    6.7362    0.0000 H   0  0  0  0  0  0  0  0  0  0  0  0
+    2.5553    3.2299    0.0000 Mg  0  0  0  0  0  0  0  0  0  0  0  0
+    3.2698    2.8174    0.0000 Br  0  0  0  0  0  0  0  0  0  0  0  0
+  1  2  2  0      
+  2  3  1  0      
+  3  4  2  0      
+  4  5  1  0      
+  5  6  2  0      
+  6  1  1  0      
+  4  7  1  0      
+  5  8  1  0      
+  3 21  1  0      
+  2 11  1  0      
+  1  9  1  0      
+  6 10  1  0      
+ 12 13  1  0      
+ 13 14  2  0      
+ 14 15  1  0      
+ 15 16  2  0      
+ 16 17  1  0      
+ 17 12  2  0      
+ 17 18  1  0      
+ 16 19  1  0      
+ 15 20  1  0      
+ 14 21  1  0      
+ 12 22  1  0      
+ 13 23  1  0      
+ 10 25  1  0      
+ 24 25  1  0      
+ 10 26  1  0      
+ 26 27  1  0      
+ 10 28  1  0      
+ 28 29  2  0      
+ 29 30  1  0      
+ 30 31  2  0      
+ 31 32  1  0      
+ 32 33  2  0      
+ 28 33  1  0      
+ 34 35  2  0      
+ 35 36  1  0      
+ 36 37  2  0      
+ 37 38  1  0      
+ 38 39  2  0      
+ 34 39  1  0      
+ 34 40  1  0      
+ 40 41  1  0      
+ 40 43  1  0      
+ 40 45  1  0      
+ 41 42  1  0      
+ 43 44  1  0      
+ 45 46  1  0      
+ 47 48  2  0      
+ 48 49  1  0      
+ 49 50  2  0      
+ 50 51  1  0      
+ 51 52  2  0      
+ 52 47  1  0      
+ 50 53  1  0      
+ 51 54  1  0      
+ 49 67  1  0      
+ 48 57  1  0      
+ 47 55  1  0      
+ 52 56  1  0      
+ 58 59  1  0      
+ 59 60  2  0      
+ 60 61  1  0      
+ 61 62  2  0      
+ 62 63  1  0      
+ 63 58  2  0      
+ 63 64  1  0      
+ 62 65  1  0      
+ 61 66  1  0      
+ 60 67  1  0      
+ 58 68  1  0      
+ 59 69  1  0      
+ 71 72  2  0      
+ 72 73  1  0      
+ 73 74  2  0      
+ 74 75  1  0      
+ 75 76  2  0      
+ 76 71  1  0      
+ 74 77  1  0      
+ 75 78  1  0      
+ 73 90  1  0      
+ 72 80  1  0      
+ 71 79  1  0      
+ 81 82  1  0      
+ 82 83  2  0      
+ 83 84  1  0      
+ 84 85  2  0      
+ 85 86  1  0      
+ 86 81  2  0      
+ 86 87  1  0      
+ 85 88  1  0      
+ 84 89  1  0      
+ 83 90  1  0      
+ 81 91  1  0      
+ 82 92  1  0      
+ 76 93  1  0      
+ 93 94  1  0      
+M  STY  1   1 SUP
+M  SLB  1   1   1
+M  SAL   1  2  24  25
+M  SBL   1  1  25
+M  SMT   1 MeO
+M  SBV   1 25   -6.3723   11.1345
+M  STY  1   2 SUP
+M  SLB  1   2   2
+M  SAL   2  2  26  27
+M  SBL   2  1  27
+M  SMT   2 OMe
+M  SBV   2 27   -5.1348   10.8325
+M  STY  1   3 SUP
+M  SLB  1   3   3
+M  SAL   3  6  28  29  30  31  32  33
+M  SBL   3  1  29
+M  SMT   3 Ph
+M  SBV   3 29   -5.5473   10.4200
+M  STY  1   4 SUP
+M  SLB  1   4   4
+M  SAL   4 13  34  35  36  37  38  39  40  41  42  43  44  45  46
+M  SMT   4 PhSi(OMe)3
+M  STY  1   5 SUP
+M  SLB  1   5   5
+M  SAL   5  2  93  94
+M  SBL   5  1  96
+M  SMT   5 MgBr
+M  SBV   5 96   -6.1108   10.5710
+M  END

src/test/resources/org/xmlcml/cml/converters/reaction/mdl/US20090039313A1-20090212-C00005.MOL

+00025001.cdx
+  ChemDraw01210917222D
+
+ 97100  0  0  0  0  0  0  0  0999 V2000
+    4.4769   -6.8912    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+    4.4769   -6.0662    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+    3.7624   -5.6537    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+    3.0480   -6.0662    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+    3.0480   -6.8912    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+    3.7624   -7.3037    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+    2.3335   -5.6537    0.0000 H   0  0  0  0  0  0  0  0  0  0  0  0
+    2.3335   -7.3037    0.0000 H   0  0  0  0  0  0  0  0  0  0  0  0
+    5.1914   -7.3037    0.0000 H   0  0  0  0  0  0  0  0  0  0  0  0
+    3.7624   -8.1287    0.0000 Si  0  0  0  0  0  0  0  0  0  0  0  0
+    5.1914   -5.6537    0.0000 H   0  0  0  0  0  0  0  0  0  0  0  0
+    3.0480   -2.7662    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+    3.0480   -3.5912    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+    3.7624   -4.0037    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+    4.4769   -3.5912    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+    4.4769   -2.7662    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+    3.7624   -2.3537    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+    3.7624   -1.5287    0.0000 H   0  0  0  0  0  0  0  0  0  0  0  0
+    5.1914   -2.3537    0.0000 H   0  0  0  0  0  0  0  0  0  0  0  0
+    5.1914   -4.0037    0.0000 H   0  0  0  0  0  0  0  0  0  0  0  0
+    3.7624   -4.8287    0.0000 O   0  0  0  0  0  0  0  0  0  0  0  0
+    2.3335   -2.3537    0.0000 H   0  0  0  0  0  0  0  0  0  0  0  0
+    2.3335   -4.0037    0.0000 H   0  0  0  0  0  0  0  0  0  0  0  0
+    4.3812   -8.0735    0.0000 O   0  0  0  0  0  0  0  0  0  0  0  0
+    5.0957   -8.4860    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+    3.8582   -8.1840    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+    3.1437   -7.7715    0.0000 O   0  0  0  0  0  0  0  0  0  0  0  0
+    3.9687   -8.4860    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+    4.3812   -9.2004    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+    5.2062   -9.2004    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+    5.6187   -8.4860    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+    5.2062   -7.7715    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+    4.3812   -7.7715    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+   -1.8912   -5.5742    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+   -1.8912   -6.3992    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+   -1.1768   -6.8117    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+   -0.4623   -6.3992    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+   -0.4623   -5.5742    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+   -1.1768   -5.1617    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+   -2.6057   -5.1617    0.0000 Si  0  0  0  0  0  0  0  0  0  0  0  0
+   -3.0182   -5.8762    0.0000 O   0  0  0  0  0  0  0  0  0  0  0  0
+   -3.8432   -5.8762    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+   -3.3202   -4.7492    0.0000 O   0  0  0  0  0  0  0  0  0  0  0  0
+   -4.0347   -5.1617    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
+   -2.1932   -4.4472    0.0000 O   0  0  0  0  0  0  0  0  0  0  0  0
+   -2.6057   -3.7327    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0