package au.com.acpfg.misc.spectra;
import java.io.IOException;
import org.knime.core.data.DataCell;
import org.knime.core.data.DataCellDataInput;
import org.knime.core.data.DataCellDataOutput;
import org.knime.core.data.DataCellSerializer;
import org.knime.core.data.DataValue;
import org.proteomecommons.io.Peak;
/**
* Implements the supported data for an MGF-derived spectra, not all of this is visible
* to users: as the renderers (currently) do not make use of some of the data. But eventually,
* they will ;-)
*
* @author andrew.cassin
*
*/
public class MGFSpectraCell extends AbstractSpectraCell {
/**
* for serialisation
*/
private static final long serialVersionUID = 837426780080298388L;
private MyMGFPeakList m_pl;
private static final DataCellSerializer<MGFSpectraCell> SERIALIZER = new MGFSpectraCellSerializer();
public MGFSpectraCell(MyMGFPeakList pl) {
assert(pl != null);
m_pl = pl;
}
public static final Class<? extends DataValue> getPreferredValueClass() {
return SpectralDataInterface.class;
}
public static final DataCellSerializer<MGFSpectraCell> getCellSerializer() {
return SERIALIZER;
}
@Override
protected boolean equalsDataCell(DataCell dc) {
return (this == dc);
}
@Override
public String getID() {
return m_pl.getTitle_safe(); // HACK: assumes title is unique!
}
@Override
public String getCharge() {
return m_pl.getCharge_safe();
}
@Override
public double[] getIntensity() {
if (getNumPeaks() == 0)
return null;
Peak[] p = m_pl.getPeaks();
double[] ret = new double[p.length];
for (int i=0; i<p.length; i++) {
ret[i] = p[i].getIntensity();
}
return ret;
}
@Override
public int getMSLevel() {
return 2; // TODO: no way to get this accurately!
}
@Override
public double[] getMZ() {
if (getNumPeaks() == 0)
return null;
Peak[] p = m_pl.getPeaks();
double[] ret = new double[p.length];
for (int i=0; i<p.length; i++) {
ret[i] = p[i].getMassOverCharge();
}
return ret;
}
@Override
public MGFSpectraCell getMyValue() {
return this;
}
@Override
public int getNumPeaks() {
return m_pl.getNumPeaks();
}
@Override
public int hashCode() {
return m_pl.hashCode();
}
@Override
public String asString(boolean round) {
StringBuilder sb = new StringBuilder();
Peak[] p = m_pl.getPeaks();
for (int i=0; i<p.length; i++) {
double mz = p[i].getMassOverCharge();
if (round) {
sb.append(Math.round(mz * 1000.0) / 1000.0);
} else {
sb.append(mz);
}
sb.append(' ');
sb.append(p[i].getIntensity());
sb.append('\n');
}
return sb.toString();
}
@Override
public double getMaxMZ() {
return m_pl.getMaxMZ();
}
@Override
public double getMinMZ() {
return m_pl.getMinMZ();
}
public String getPepmass() {
return m_pl.getPepmass_safe();
}
/**
* Implement our own mechanism to persist MGF spectra objects, typically this is faster
* than using java.lang.Serializable but we do this not just for speed but for correct
* instantiation of the objects
*
* @author andrew.cassin
*
*/
private static class MGFSpectraCellSerializer implements DataCellSerializer<MGFSpectraCell> {
@Override
public MGFSpectraCell deserialize(final DataCellDataInput input) throws IOException {
MyMGFPeakList mgf = new MyMGFPeakList();
// 1. load the peaklist
int n_peaks = input.readInt();
double[] mz = new double[n_peaks];
double[] intensity = new double[n_peaks];
for (int i=0; i<n_peaks; i++) {
mz[i] = input.readDouble();
intensity[i] = input.readDouble();
}
mgf.setPeaks(mz, intensity);
// 2. load metadata
String title = input.readUTF();
mgf.setTitle(title);
String pepmass = input.readUTF();
mgf.setPepMass(pepmass);
String charge = input.readUTF();
mgf.setCharge(charge);
int tc = input.readInt();
mgf.setTandemCount(tc);
return new MGFSpectraCell(mgf);
}
@Override
public void serialize(final MGFSpectraCell spectra, final DataCellDataOutput output)
throws IOException {
if (spectra == null || output == null)
throw new IOException("Bad data given to MGFSpectraCellInitializer::serialize()");
// 1. write output peaks (NB: same length arrays)
int n_peaks = spectra.getNumPeaks();
output.writeInt(n_peaks);
double[] mz = spectra.getMZ();
double[] intensity = spectra.getIntensity();
for (int i=0; i<n_peaks; i++) {
output.writeDouble(mz[i]);
output.writeDouble(intensity[i]);
}
// 2. save header
MyMGFPeakList pl = spectra.m_pl;
output.writeUTF(pl.getTitle_safe());
output.writeUTF(pl.getPepmass_safe());
output.writeUTF(pl.getCharge_safe());
output.writeInt(pl.getTandemCount());
}
}
}