/* * EuroCarbDB, a framework for carbohydrate bioinformatics * * Copyright (c) 2006-2009, Eurocarb project, or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU * Lesser General Public License, as published by the Free Software Foundation. * A copy of this license accompanies this distribution in the file LICENSE.txt. * * 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. * * Last commit: $Rev: 1210 $ by $Author: glycoslave $ on $Date:: 2009-06-12 #$ */ package org.eurocarbdb.application.glycoworkbench; import org.eurocarbdb.application.glycanbuilder.*; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.xml.sax.SAXException; import javax.xml.transform.sax.TransformerHandler; import org.xml.sax.helpers.AttributesImpl; /** Represent a peak annotated with an intact or fragment glycan molecule. An empty structure can represent a non annotated peak @author Alessio Ceroni (a.ceroni@imperial.ac.uk) */ public class PeakAnnotation implements Comparable<PeakAnnotation>, SAXUtils.SAXWriter { protected Peak peak; protected Annotation annotation; /** Create an empty object */ public PeakAnnotation() { peak = new Peak(); annotation = new Annotation(); } /** Create a non-annotated peak @param _mz the mass/charge value of the peak @param _int intensity value of the peak */ public PeakAnnotation(double _mz, double _int) { peak = new Peak(_mz,_int); annotation = new Annotation(); } /** Create a non-annotated peak */ public PeakAnnotation(Peak p) { peak = (p!=null) ?p.clone() :new Peak(); annotation = new Annotation(); } /** Create an annotated peak @param f the annotation */ public PeakAnnotation(Peak p, FragmentEntry f) { peak = (p!=null) ?p.clone() :new Peak(); annotation = new Annotation(f); } /** Create an annotated peak @param f the annotation @param c the charges associated with this annotation */ public PeakAnnotation(Peak p, FragmentEntry f, IonCloud c) { peak = (p!=null) ?p.clone() :new Peak(); annotation = new Annotation(f,c); } /** Create an annotated peak @param f the annotation @param c the charges associated with this annotation @param ex the exchanges associated with this annotation */ public PeakAnnotation(Peak p, FragmentEntry f, IonCloud c, IonCloud ex) { peak = (p!=null) ?p.clone() :new Peak(); annotation = new Annotation(f,c,ex); } /** Create an annotated peak @param a the annotation */ public PeakAnnotation(Peak p, Annotation a) { peak = (p!=null) ?p.clone() :new Peak(); annotation = (a!=null) ?a.clone() :new Annotation(); } /** Return a copy of this peak annotation */ public PeakAnnotation clone() { return new PeakAnnotation(peak,annotation); } public int compareTo(PeakAnnotation pa) { if( pa==null ) return 1; // compare peak int cp = this.peak.compareTo(pa.peak); if( cp!=0 ) return cp; // compare accuracy double ma1 = Math.round(this.getAccuracy()*10000); double ma2 = Math.round(pa.getAccuracy()*10000); if( ma1<ma2 ) return -1; if( ma1>ma2 ) return 1; // compare annotations return this.annotation.compareTo(pa.annotation); } public boolean equals(Object other) { if( !(other instanceof PeakAnnotation) ) return false; PeakAnnotation pa = (PeakAnnotation)other; return (peak.equals(pa.peak) && annotation.equals(pa.annotation)); } public int hashCode() { return peak.hashCode() + annotation.hashCode(); } /** Return the peak associated with this peak annotation */ public Peak getPeak() { return peak; } /** Return the annotation associated with this peak annotation */ public Annotation getAnnotation() { return annotation; } /** Return the mass/charge value of the peak associated with this peak annotation */ public Double getMZ() { return peak.getMZ(); } /** Return the intensity value of the peak associated with this peak annotation */ public Double getIntensity() { return peak.getIntensity(); } /** Return the annotation associated with this peak annotation */ public FragmentEntry getFragmentEntry() { return annotation.getFragmentEntry(); } /** Return the glycan structure associated with this peak annotation @see FragmentEntry#getFragment */ public Glycan getFragment() { return annotation.getFragmentEntry().fragment; } /** Return the type of fragment associated with this peak annotation @see FragmentEntry#getName */ public String getFragmentType() { return annotation.getFragmentEntry().name; } /** Return <code>true</code> if the peak annotation contains a non-empty structure */ public boolean isAnnotated() { return !annotation.isEmpty(); } /** Return the difference between experimental and predicted mass/charge values */ public double getAccuracy() { return annotation.getAccuracy(peak); } /** Return the difference between experimental and predicted mass/charge values in PPM */ public double getAccuracyPPM() { return annotation.getAccuracyPPM(peak); } /** Return the predicted mass/charge value associated with the peak annotation */ public double getAnnotationMZ() { return annotation.getMZ(); } /** Return the number of charges associated with the peak annotation */ public int getAnnotationZ() { return annotation.getZ(); } /** Return the list of charges associated with the peak annotation */ public IonCloud getIons() { return annotation.getIons(); } /** Return the list of exchanges associated with the peak annotation */ public IonCloud getNeutralExchanges() { return annotation.getNeutralExchanges(); } // serialization public String toString() { return peak + " " + annotation; } /** Create a new object from its XML representation as part of a DOM tree. */ static public PeakAnnotation fromXML(Node pa_node) throws Exception { PeakAnnotation ret = new PeakAnnotation(); Node peak_node = XMLUtils.assertChild(pa_node,"Peak"); ret.peak = Peak.fromXML(peak_node); Node ann_node = XMLUtils.assertChild(pa_node,"Annotation"); ret.annotation = Annotation.fromXML(ann_node); return ret; } /** Create an XML representation of this object to be part of a DOM tree. */ public Element toXML(Document document) { if( document==null ) return null; // create root node Element pa_node = document.createElement("PeakAnnotation"); if( pa_node==null ) return null; // add peak Element peak_node = peak.toXML(document); if( peak_node==null ) return null; pa_node.appendChild(peak_node); // add annotation Element ann_node = annotation.toXML(document); if( ann_node==null ) return null; pa_node.appendChild(ann_node); return pa_node; } /** Default SAX handler to read a representation of this object from an XML stream. */ public static class SAXHandler extends SAXUtils.ObjectTreeHandler { public boolean isElement(String namespaceURI, String localName, String qName) { return qName.equals(getNodeElementName()); } public static String getNodeElementName() { return "PeakAnnotation"; } protected SAXUtils.ObjectTreeHandler getHandler(String namespaceURI, String localName, String qName) { if( qName.equals(Peak.SAXHandler.getNodeElementName()) ) return new Peak.SAXHandler(); if( qName.equals(Annotation.SAXHandler.getNodeElementName()) ) return new Annotation.SAXHandler(); return null; } protected Object finalizeContent(String namespaceURI, String localName, String qName) throws SAXException{ Peak p = (Peak)getSubObject(Peak.SAXHandler.getNodeElementName(),true); Annotation a = (Annotation)getSubObject(Annotation.SAXHandler.getNodeElementName(),true); return new PeakAnnotation(p,a); } } public void write(TransformerHandler th) throws SAXException { th.startElement("","","PeakAnnotation",new AttributesImpl()); peak.write(th); annotation.write(th); th.endElement("","","PeakAnnotation"); } }