/***************************************************************************** * Copyright (c) 2008 Bioclipse Project * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * *****************************************************************************/ package spok.parser; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.PrintWriter; import java.io.StringWriter; import java.net.URL; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Properties; import net.bioclipse.spectrum.Activator; import net.bioclipse.spectrum.editor.MetadataUtils; import net.bioclipse.cml.contenttypes.CmlFileDescriber; import nu.xom.Element; import nu.xom.Nodes; import nu.xom.ParsingException; import nu.xom.ValidityException; import nu.xom.XPathContext; import org.apache.log4j.Logger; import org.eclipse.core.runtime.FileLocator; import org.eclipse.core.runtime.Platform; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.MessageBox; import org.eclipse.swt.widgets.Shell; import org.jcamp.parser.JCAMPException; import org.jcamp.spectrum.ArrayData; import org.jcamp.spectrum.IDataArray1D; import org.jcamp.spectrum.IOrderedDataArray1D; import org.jcamp.spectrum.IRSpectrum; import org.jcamp.spectrum.MassSpectrum; import org.jcamp.spectrum.NMRSpectrum; import org.jcamp.spectrum.OrderedArrayData; import org.jcamp.spectrum.Peak1D; import org.jcamp.spectrum.Spectrum; import org.jcamp.spectrum.Spectrum1D; import org.jcamp.units.CommonUnit; import org.xmlcml.cml.base.CMLElement; import org.xmlcml.cml.base.CMLElements; import org.xmlcml.cml.element.CMLMetadata; import org.xmlcml.cml.element.CMLMetadataList; import org.xmlcml.cml.element.CMLPeak; import org.xmlcml.cml.element.CMLSpectrum; import spok.utils.SpectrumUtils; public class CMLToJcampSpectrumMapper { private static final Logger logger = Logger.getLogger(CMLToJcampSpectrumMapper.class); private static Spectrum1D jcampSpectrum; private static boolean fullspec; public static Spectrum mapCMLSpectrumToJcamp(CMLSpectrum spectrum) { //shk3: I added the jcampSpectrum=null since if no peaks are in the spectrum and //the method was already used before, the old spectrum will be used and the //type will be that of the old spectrum no matter what is it now (in mapPeaks, //a new spectrum is created always, but this is not always called) jcampSpectrum=null; fullspec = false; if (spectrum.getSpectrumDataElements() != null && spectrum.getSpectrumDataElements().size() > 0) { fullspec = true; } mapPeaks(spectrum); mapData(spectrum); try{ mapNotes(spectrum); }catch(Exception ex){ StringWriter strWr = new StringWriter(); PrintWriter prWr = new PrintWriter(strWr); ex.printStackTrace(prWr); logger.error(strWr.toString()); MessageBox mb = new MessageBox(new Shell(), SWT.OK | SWT.ICON_WARNING); mb.setText("Error mapping nodes"); mb.setMessage("Mapping the CML metadata to JCAMP nodes failed. The JCMAMP file will not contain all information from the model!"); mb.open(); } String title = spectrum.getTitle(); jcampSpectrum.setTitle(title); return (Spectrum) jcampSpectrum; } private static void mapPeaks(CMLSpectrum spectrum) { if (spectrum.getPeakListElements().size() != 0) { List<CMLElement> peaks = SpectrumUtils.getPeakElements(spectrum); Iterator<CMLElement> it = peaks.iterator(); Peak1D[] jcampPeaks = new Peak1D[peaks.size()]; int i = 0; while (it.hasNext()) { CMLPeak peak = (CMLPeak) it.next(); if (peak.getXValue() != 0 || peak.getYValue() != 0) { Peak1D jcampPeak = new Peak1D(peak.getXValue(), peak .getYValue()); jcampPeak.setHeight(peak.getYValue()); jcampPeaks[i] = jcampPeak; i += 1; } } if (spectrum.getType().compareTo("massSpectrum") == 0) { double[][] xy = null; try { xy = SpectrumUtils.peakTableToPeakSpectrum(jcampPeaks); } catch (JCAMPException e) { StringWriter strWr = new StringWriter(); PrintWriter prWr = new PrintWriter(strWr); e.printStackTrace(prWr); logger.error(strWr.toString()); } IOrderedDataArray1D x = new OrderedArrayData(xy[0], CommonUnit.mz); IDataArray1D y = new ArrayData(xy[1], CommonUnit.intensity); if (!fullspec) { jcampSpectrum = new MassSpectrum(x, y, false); } else { jcampSpectrum = new MassSpectrum(x, y, true); } } else if (spectrum.getType().compareTo("NMR") == 0) { double[][] xy = null; ArrayList<Object> list = getRefFreNuc(spectrum); double reference = 0; if (list.get(0) != null) { reference = ((Double) list.get(0)).doubleValue(); } double freq = ((Double) list.get(1)).doubleValue(); String nucleus = (String) list.get(2); try { xy = SpectrumUtils.peakTableToPeakSpectrum(jcampPeaks); } catch (JCAMPException e) { StringWriter strWr = new StringWriter(); PrintWriter prWr = new PrintWriter(strWr); e.printStackTrace(prWr); logger.error(strWr.toString()); } IOrderedDataArray1D x = new OrderedArrayData(xy[0], CommonUnit.mz); IDataArray1D y = new ArrayData(xy[1], CommonUnit.intensity); if (!fullspec) { jcampSpectrum = new NMRSpectrum(x, y, nucleus, freq, reference, false, Activator.getDefault().getModePreference()); } else { jcampSpectrum = new NMRSpectrum(x, y, nucleus, freq, reference, true, Activator.getDefault().getModePreference()); } }else if (spectrum.getType().compareTo("IR") == 0) { double[][] xy = null; try { xy = SpectrumUtils.peakTableToPeakSpectrum(jcampPeaks); } catch (JCAMPException e) { e.printStackTrace(); StringWriter strWr = new StringWriter(); PrintWriter prWr = new PrintWriter(strWr); e.printStackTrace(prWr); logger.error(strWr.toString()); } IOrderedDataArray1D x = new OrderedArrayData(xy[0], CommonUnit.perCM); IDataArray1D y = new ArrayData(xy[1], CommonUnit.intensity); if (!fullspec) { jcampSpectrum = new IRSpectrum(x, y, false); } else { jcampSpectrum = new IRSpectrum(x, y, true); } }else{ MessageDialog.openError(new Shell(), "Unknown spectrum type", "The spectrum had no known type. The file net.bioclipse.spectrum/net/bioclipse/spectrum/editor/spec.xml contains valid types!"); return; } jcampSpectrum.setPeakTable(jcampPeaks); } } private static void mapData(CMLSpectrum spectrum) { // ArrayList xyData = spectrum.getXYData(); double[] jcampXData = null; double[] jcampYData = null; if (SpectrumUtils.getXDataElements(spectrum) != null) { jcampXData = SpectrumUtils.getXDataElements(spectrum); } if (SpectrumUtils.getYDataElements(spectrum) != null) { jcampYData = SpectrumUtils.getYDataElements(spectrum); } else { jcampXData = new double[0]; jcampYData = new double[0]; } OrderedArrayData xData = null; ArrayData yData = null; if (spectrum.getType().compareTo("massSpectrum") == 0) { xData = new OrderedArrayData(jcampXData, CommonUnit.mz); yData = new ArrayData(jcampYData, CommonUnit.percentIntensity); } else if (spectrum.getType().compareTo("NMR") == 0) { xData = new OrderedArrayData(jcampXData, CommonUnit.ppm); yData = new ArrayData(jcampYData, CommonUnit.percentIntensity); } else if (spectrum.getType().compareTo("IR") == 0) { xData = new OrderedArrayData(jcampXData, CommonUnit.perCM); yData = new ArrayData(jcampYData, CommonUnit.percentIntensity); } if (jcampSpectrum != null) { jcampSpectrum.setData(xData, yData); // jcampSpectrum.setXData(xData); // jcampSpectrum.setYData(yData); } else { if (xData.getUnit() == CommonUnit.ppm) { ArrayList<Object> list = getRefFreNuc(spectrum); double reference = ((Double) list.get(0)).doubleValue(); double freq = ((Double) list.get(1)).doubleValue(); String nucleus = (String) list.get(2); jcampSpectrum = new NMRSpectrum(xData, yData, nucleus, freq, reference, true, Activator.getDefault().getModePreference()); } else if (xData.getUnit() == CommonUnit.mz) { jcampSpectrum = new MassSpectrum(xData, yData, true); } else if (xData.getUnit() == CommonUnit.perCM) { jcampSpectrum = new IRSpectrum(xData, yData, true); } } } private static ArrayList<Object> getRefFreNuc(CMLSpectrum spectrum) { ArrayList<Object> list = new ArrayList<Object>(); CMLElements<CMLMetadataList> mlists = spectrum .getMetadataListElements(); Iterator<CMLMetadataList> it = mlists.iterator(); Double refVal = new Double(0); Double freqVal = new Double(1); String nucVal = null; while (it.hasNext()) { CMLMetadataList mlist = it.next(); List<CMLMetadata> ref = MetadataUtils.getMetadataDescendantsByName(mlist.getMetadataDescendants(),"jcampdx:SHIFTREFERENCE"); String val; if (ref != null && ref.size() > 0) { val = ref.get(0).getValue().trim(); if (val.length() > 0) { refVal = new Double(ref.get(0).getValue()); } } List<CMLMetadata> freq = MetadataUtils.getMetadataDescendantsByName(mlist.getMetadataDescendants(),"jcampdx:OBSERVEFREQUENCY"); if (freq != null && freq.size() > 0) { val = freq.get(0).getValue().trim(); if (val.length() > 0) { freqVal = new Double(freq.get(0).getValue()); } } List<CMLMetadata> nuc = MetadataUtils.getMetadataDescendantsByName(mlist.getMetadataDescendants(),"jcampdx:OBSERVENUCLEUS"); if (nuc != null && nuc.size() > 0) { nucVal = nuc.get(0).getValue(); } } list.add(refVal); list.add(freqVal); list.add(nucVal); return list; } private static void mapNotes(CMLSpectrum spectrum) throws ValidityException, ParsingException, IOException { HashMap<String, String> notes = SpectrumUtils.getNotesAsMap(spectrum); Iterator<String> notesIterator = notes.keySet().iterator(); boolean title=false; while (notesIterator.hasNext()) { String id = (String) notesIterator.next(); String content = (String) notes.get(id); Properties notesProps = new Properties(); URL varPluginUrl = Platform.getBundle( "net.bioclipse.spectrum").getEntry("/"); String varInstallPath = null; try { varInstallPath = FileLocator.toFileURL(varPluginUrl).getFile(); } catch (IOException e) { StringWriter strWr = new StringWriter(); logger.error(strWr.toString()); } File notePropsFile = new File(varInstallPath + "notes.properties"); FileInputStream inStream = new FileInputStream(notePropsFile); notesProps.load(inStream); Element jcampDict = SpectrumUtils.readJCampDict(); XPathContext xpathContext = new XPathContext("jcampDictNS", CmlFileDescriber.NS_CML); Nodes resultNodes = jcampDict.query("//jcampDictNS:entry[@id='" + id +"']", xpathContext); String name = null; String jcampName = null; if (resultNodes.size() == 1) { Element result = (Element) resultNodes.get(0); if (result != null) { name = result.getAttributeValue("term"); } } if (name != null) { jcampName = (String) notesProps.get(name + ".jcamp"); } jcampName = (String) notesProps.get(id + ".jcamp"); if (jcampName != null) { if(jcampName.equals("TITLE")){ if(!title){ jcampSpectrum.setNote(jcampName, content); title=true; } } } else { if (id!=null && id.startsWith("dot")) { id = "." + id.substring(3); } if(id!=null && content!=null && !id.equals("TITLE")) jcampSpectrum.setNote(id, content); } } } }