/**
* Created by IntelliJ IDEA. User: Lennart Date: 11-mei-2004 Time: 16:34:34
*/
package com.compomics.util.gui.spectrum;
import com.compomics.util.experiment.biology.AminoAcidPattern;
import com.compomics.util.experiment.biology.AminoAcidSequence;
import com.compomics.util.experiment.biology.Ion;
import com.compomics.util.experiment.biology.NeutralLoss;
import com.compomics.util.experiment.biology.Peptide;
import com.compomics.util.experiment.biology.ions.PeptideFragmentIon;
import com.compomics.util.experiment.biology.ions.TagFragmentIon;
import com.compomics.util.experiment.identification.matches.IonMatch;
import com.compomics.util.experiment.identification.matches.ModificationMatch;
import com.compomics.util.experiment.identification.amino_acid_tags.Tag;
import com.compomics.util.experiment.identification.amino_acid_tags.TagComponent;
import com.compomics.util.experiment.biology.MassGap;
import com.compomics.util.gui.interfaces.SpectrumAnnotation;
import org.apache.log4j.Logger;
import com.compomics.util.interfaces.SpectrumFile;
import javax.swing.*;
import javax.swing.border.EtchedBorder;
import java.awt.*;
import java.util.*;
import java.util.ArrayList;
/*
* CVS information:
*
* $Revision: 1.9 $ $Date: 2009/08/17 15:15:28 $
*/
/**
* This class presents a JPanel that will hold and display a mass spectrum in
* centroid or profile mode.
*
* @author Lennart Martens
* @author Harald Barsnes
* @version $Id: SpectrumPanel.java,v 1.9 2009/08/17 15:15:28 lennart Exp $
*/
public class SpectrumPanel extends GraphicsPanel {
/**
* Class specific log4j logger for SpectrumPanel instances.
*/
static Logger logger = Logger.getLogger(SpectrumPanel.class);
/**
* The color used for the peaks. Default to red.
*/
private Color spectrumPeakColor = Color.RED;
/**
* The color used for the profile mode spectra. Defaults to pink.
*/
private Color spectrumProfileModeLineColor = Color.PINK;
/**
* Color map for the ion annotation.
*/
private static HashMap<Ion.IonType, HashMap<Integer, HashMap<String, Color>>> colorMap = new HashMap<Ion.IonType, HashMap<Integer, HashMap<String, Color>>>();
/**
* This constructor creates a SpectrumPanel based on the spectrum
* information in the specified SpectrumFile as an interactive lines plot.
*
* @param aSpecFile SpectrumFile with the information about masses and
* intensities that will be copied here. Note that mass-sorting will take
* place in this step as well.
*/
public SpectrumPanel(SpectrumFile aSpecFile) {
this(aSpecFile, DrawingStyle.LINES, true);
}
/**
* This constructor creates a SpectrumPanel based on the spectrum
* information in the specified SpectrumFile as a line plot.
*
* @param aSpecFile SpectrumFile with the information about masses and
* intensities that will be copied here. Note that mass-sorting will take
* place in this step as well.
* @param aEnableInteraction boolean that specifies whether user-derived
* events should be caught and dealt with.
*/
public SpectrumPanel(SpectrumFile aSpecFile, boolean aEnableInteraction) {
this(aSpecFile, DrawingStyle.LINES, aEnableInteraction);
}
/**
* This constructor creates a SpectrumPanel based on the spectrum
* information in the specified SpectrumFile with the specified drawing
* style.
*
* @param aSpecFile SpectrumFile with the information about masses and
* intensities that will be copied here. Note that mass-sorting will take
* place in this step as well.
* @param aDrawStyle the drawing style to use.
* @param aEnableInteraction boolean that specifies whether user-derived
* events should be caught and dealt with.
*/
public SpectrumPanel(SpectrumFile aSpecFile, DrawingStyle aDrawStyle, boolean aEnableInteraction) {
this(aSpecFile, aDrawStyle, aEnableInteraction, null);
}
/**
* This constructor creates a SpectrumPanel based on the spectrum
* information in the specified SpectrumFile with the specified drawing
* style.
*
* @param aSpecFile SpectrumFile with the information about masses and
* intensities that will be copied here. Note that mass-sorting will take
* place in this step as well.
* @param aDrawStyle the drawing style to use.
* @param aEnableInteraction boolean that specifies whether user-derived
* events should be caught and dealt with.
* @param aSpectrumFilenameColor Color with the color for the
* spectrumfilename on the panel can be 'null' for default coloring.
*/
public SpectrumPanel(SpectrumFile aSpecFile, DrawingStyle aDrawStyle, boolean aEnableInteraction, Color aSpectrumFilenameColor) {
this(aSpecFile, aDrawStyle, aEnableInteraction, aSpectrumFilenameColor, 50, false, true, true);
}
/**
* This constructor creates a SpectrumPanel based on the spectrum
* information in the specified SpectrumFile with the specified drawing
* style.
*
* @param aSpecFile SpectrumFile with the information about masses and
* intensities that will be copied here. Note that mass-sorting will take
* place in this step as well.
* @param aDrawStyle the drawing style to use.
* @param aEnableInteraction boolean that specifies whether user-derived
* events should be caught and dealt with.
* @param aSpectrumFilenameColor Color with the color for the
* spectrumfilename on the panel can be 'null' for default coloring.
* @param aMaxPadding int the sets the maximum padding size.
* @param aShowFileName boolean that specifies if the file name should be
* shown in the panel
*/
public SpectrumPanel(SpectrumFile aSpecFile, DrawingStyle aDrawStyle, boolean aEnableInteraction, Color aSpectrumFilenameColor,
int aMaxPadding, boolean aShowFileName) {
this(aSpecFile, aDrawStyle, aEnableInteraction, aSpectrumFilenameColor, aMaxPadding, aShowFileName, true, true);
}
/**
* This constructor creates a SpectrumPanel based on the spectrum
* information in the specified SpectrumFile with the specified drawing
* style.
*
* @param aSpecFile SpectrumFile with the information about masses and
* intensities that will be copied here. Note that mass-sorting will take
* place in this step as well.
* @param aDrawStyle the drawing style to use.
* @param aEnableInteraction boolean that specifies whether user-derived
* events should be caught and dealt with.
* @param aSpectrumFilenameColor Color with the color for the spectrum
* filename in the panel can be 'null' for default coloring.
* @param aMaxPadding int the sets the maximum padding size.
* @param aShowFileName boolean that specifies if the file name should be
* shown in the panel
* @param aShowPrecursorDetails boolean that specifies if the precursor
* details should be shown in the panel
* @param aShowResolution boolean that specifies if the resolution should be
* shown in the panel
*/
public SpectrumPanel(SpectrumFile aSpecFile, DrawingStyle aDrawStyle, boolean aEnableInteraction, Color aSpectrumFilenameColor,
int aMaxPadding, boolean aShowFileName, boolean aShowPrecursorDetails, boolean aShowResolution) {
this(aSpecFile, aDrawStyle, aEnableInteraction, aSpectrumFilenameColor, aMaxPadding, aShowFileName, aShowPrecursorDetails, aShowResolution, 0);
}
/**
* This constructor creates a SpectrumPanel based on the spectrum
* information in the specified SpectrumFile with the specified drawing
* style.
*
* @param aSpecFile SpectrumFile with the information about masses and
* intensities that will be copied here. Note that mass-sorting will take
* place in this step as well.
* @param aDrawStyle the drawing style to use.
* @param aEnableInteraction boolean that specifies whether user-derived
* events should be caught and dealt with.
* @param aSpectrumFilenameColor Color with the color for the spectrum
* filename in the panel can be 'null' for default coloring.
* @param aMaxPadding int the sets the maximum padding size.
* @param aShowFileName boolean that specifies if the file name should be
* shown in the panel
* @param aShowPrecursorDetails boolean that specifies if the precursor
* details should be shown in the panel
* @param aShowResolution boolean that specifies if the resolution should be
* shown in the panel
* @param aMSLevel int with the ms level for the spectrum
*/
public SpectrumPanel(SpectrumFile aSpecFile, DrawingStyle aDrawStyle, boolean aEnableInteraction, Color aSpectrumFilenameColor,
int aMaxPadding, boolean aShowFileName, boolean aShowPrecursorDetails, boolean aShowResolution, int aMSLevel) {
this(aSpecFile, aDrawStyle, aEnableInteraction, aSpectrumFilenameColor, aMaxPadding, aShowFileName, aShowPrecursorDetails, aShowResolution, aMSLevel, false);
}
/**
* This constructor creates a SpectrumPanel based on the spectrum
* information in the specified SpectrumFile with the specified drawing
* style.
*
* @param aSpecFile SpectrumFile with the information about masses and
* intensities that will be copied here. Note that mass-sorting will take
* place in this step as well.
* @param aDrawStyle the drawing style to use.
* @param aEnableInteraction boolean that specifies whether user-derived
* events should be caught and dealt with.
* @param aSpectrumFilenameColor Color with the color for the spectrum
* filename in the panel can be 'null' for default coloring.
* @param aMaxPadding int the sets the maximum padding size.
*
* @param aShowFileName boolean that specifies if the file name should be
* shown in the panel
* @param aShowPrecursorDetails boolean that specifies if the precursor
* details should be shown in the panel
* @param aShowResolution boolean that specifies if the resolution should be
* shown in the panel
* @param aMSLevel int with the ms level for the spectrum, set to 0 if ms
* level is unknown
* @param aProfileMode boolean if set to true the spectrum will be drawn in
* profile mode
*/
public SpectrumPanel(SpectrumFile aSpecFile, DrawingStyle aDrawStyle, boolean aEnableInteraction,
Color aSpectrumFilenameColor, int aMaxPadding,
boolean aShowFileName, boolean aShowPrecursorDetails, boolean aShowResolution,
int aMSLevel, boolean aProfileMode) {
this.iCurrentDrawStyle = aDrawStyle;
this.iSpecPanelListeners = new ArrayList();
this.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED));
this.setBackground(Color.WHITE);
if (aSpecFile != null) {
dataSetCounter = 0;
this.processSpectrumFile(aSpecFile, spectrumPeakColor, spectrumProfileModeLineColor);
}
if (aEnableInteraction) {
this.addListeners();
}
this.iFilenameColor = aSpectrumFilenameColor;
this.maxPadding = aMaxPadding;
this.showFileName = aShowFileName;
this.showPrecursorDetails = aShowPrecursorDetails;
this.showResolution = aShowResolution;
this.iMSLevel = aMSLevel;
if (aProfileMode) {
this.currentGraphicsPanelType = GraphicsPanelType.profileSpectrum;
} else {
this.currentGraphicsPanelType = GraphicsPanelType.centroidSpectrum;
}
}
/**
* This constructor creates a SpectrumPanel based on the passed parameters.
* This constructor will be used to annotate matched ions on the spectrum
* panels.
*
* @param aXAxisData double[] with all the x-axis values.
* @param aYAxisData double[] with all the y-axis values.
* @param aPrecursorMZ double with the precursor mass.
* @param aPrecursorCharge String with the precursor intensity.
* @param aFileName String with the title of the Query.
*/
public SpectrumPanel(double[] aXAxisData, double[] aYAxisData, double aPrecursorMZ, String aPrecursorCharge, String aFileName) {
this(aXAxisData, aYAxisData, aPrecursorMZ, aPrecursorCharge, aFileName, 50, false, true, true);
}
/**
* This constructor creates a SpectrumPanel based on the passed parameters.
* This constructor will be used to annotate matched ions on the spectrum
* panels.
*
* @param aXAxisData double[] with all the x-axis values.
* @param aYAxisData double[] with all the y-axis values.
* @param aPrecursorMZ double with the precursor mass.
* @param aPrecursorCharge String with the precursor intensity.
* @param aFileName String with the title of the Query.
* @param aShowFileName boolean that specifies if the file name should be
* shown in the panel.
*/
public SpectrumPanel(double[] aXAxisData, double[] aYAxisData, double aPrecursorMZ, String aPrecursorCharge, String aFileName,
boolean aShowFileName) {
this(aXAxisData, aYAxisData, aPrecursorMZ, aPrecursorCharge, aFileName, 50, aShowFileName, true, true);
}
/**
* This constructor creates a SpectrumPanel based on the passed parameters.
* This constructor will be used to annotate matched ions on the spectrum
* panels.
*
* @param aXAxisData double[] with all the x-axis values.
* @param aYAxisData double[] with all the y-axis values.
* @param aPrecursorMZ double with the precursor mass.
* @param aPrecursorCharge String with the precursor intensity.
* @param aFileName String with the title of the Query.
* @param aMaxPadding int the sets the maximum padding size.
* @param aShowFileName boolean that specifies if the file name should be
* shown in the panel.
*/
public SpectrumPanel(double[] aXAxisData, double[] aYAxisData, double aPrecursorMZ, String aPrecursorCharge,
String aFileName, int aMaxPadding, boolean aShowFileName) {
this(aXAxisData, aYAxisData, aPrecursorMZ, aPrecursorCharge, aFileName, aMaxPadding, aShowFileName, true, true);
}
/**
* This constructor creates a SpectrumPanel based on the passed parameters.
* This constructor will be used to annotate matched ions on the spectrum
* panels.
*
* @param aXAxisData double[] with all the x-axis values.
* @param aYAxisData double[] with all the y-axis values.
* @param aPrecursorMZ double with the precursor mass.
* @param aPrecursorCharge String with the precursor intensity.
* @param aFileName String with the title of the Query.
* @param aMaxPadding int the sets the maximum padding size.
* @param aShowFileName boolean that specifies if the file name should be
* shown in the panel
* @param aShowPrecursorDetails boolean that specifies if the precursor
* details should be shown in the panel
* @param aShowResolution boolean that specifies if the resolution should be
* shown in the panel
*/
public SpectrumPanel(double[] aXAxisData, double[] aYAxisData, double aPrecursorMZ, String aPrecursorCharge,
String aFileName, int aMaxPadding, boolean aShowFileName,
boolean aShowPrecursorDetails, boolean aShowResolution) {
this(aXAxisData, aYAxisData, aPrecursorMZ, aPrecursorCharge, aFileName, aMaxPadding,
aShowFileName, aShowPrecursorDetails, aShowResolution, 0);
}
/**
* This constructor creates a SpectrumPanel based on the passed parameters.
* This constructor will be used to annotate matched ions on the spectrum
* panels.
*
* @param aXAxisData double[] with all the x-axis values.
* @param aYAxisData double[] with all the y-axis values.
* @param aPrecursorMZ double with the precursor mass.
* @param aPrecursorCharge String with the precursor intensity.
* @param aFileName String with the title of the Query.
* @param aMaxPadding int the sets the maximum padding size.
* @param aShowFileName boolean that specifies if the file name should be
* shown in the panel
* @param aShowPrecursorDetails boolean that specifies if the precursor
* details should be shown in the panel
* @param aShowResolution boolean that specifies if the resolution should be
* shown in the panel
* @param aMSLevel int with the ms level for the spectrum, set to 0 if ms
* level is unknown
*/
public SpectrumPanel(double[] aXAxisData, double[] aYAxisData, double aPrecursorMZ, String aPrecursorCharge,
String aFileName, int aMaxPadding, boolean aShowFileName,
boolean aShowPrecursorDetails, boolean aShowResolution, int aMSLevel) {
this(aXAxisData, aYAxisData, aPrecursorMZ, aPrecursorCharge, aFileName, aMaxPadding,
aShowFileName, aShowPrecursorDetails, aShowResolution, aMSLevel, false);
}
/**
* This constructor creates a SpectrumPanel based on the passed parameters.
* This constructor will be used to annotate matched ions on the spectrum
* panels.
*
* @param aXAxisData double[] with all the x-axis values.
* @param aYAxisData double[] with all the y-axis values.
* @param aPrecursorMZ double with the precursor mass.
* @param aPrecursorCharge String with the precursor charge.
* @param aFileName String with the title of the Query.
* @param aMaxPadding int the sets the maximum padding size.
* @param aShowFileName boolean that specifies if the file name should be
* shown in the panel
* @param aShowPrecursorDetails boolean that specifies if the precursor
* details should be shown in the panel
* @param aShowResolution boolean that specifies if the resolution should be
* shown in the panel
* @param aMSLevel int with the ms level for the spectrum, set to 0 if ms
* level is unknown
* @param aProfileMode boolean if set to true the spectrum will be drawn in
* profile mode
*/
public SpectrumPanel(double[] aXAxisData, double[] aYAxisData, double aPrecursorMZ, String aPrecursorCharge,
String aFileName, int aMaxPadding, boolean aShowFileName,
boolean aShowPrecursorDetails, boolean aShowResolution, int aMSLevel,
boolean aProfileMode) {
this.iCurrentDrawStyle = DrawingStyle.LINES;
this.iSpecPanelListeners = new ArrayList();
this.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED));
this.setBackground(Color.WHITE);
dataSetCounter = 0;
processXAndYData(aXAxisData, aYAxisData, spectrumPeakColor, spectrumProfileModeLineColor);
iPrecursorMZ = aPrecursorMZ;
iPrecursorCharge = aPrecursorCharge;
iFilename = aFileName;
this.maxPadding = aMaxPadding;
this.showFileName = aShowFileName;
this.showPrecursorDetails = aShowPrecursorDetails;
this.showResolution = aShowResolution;
this.iMSLevel = aMSLevel;
if (aProfileMode) {
this.currentGraphicsPanelType = GraphicsPanelType.profileSpectrum;
} else {
this.currentGraphicsPanelType = GraphicsPanelType.centroidSpectrum;
}
this.addListeners();
}
/**
* Add a mirrored spectrum (or chromatogram).
*
* @param aXAxisData the x axis data
* @param aYAxisData the y axis data
* @param aPrecursorMZ the precursor m/z
* @param aPrecursorCharge the precursor charge
* @param aFileName the file name
* @param aProfileMode if the spectrum is to be drawn in profile mode
* @param aSpectrumPeakColor the spectrum peak color
* @param aSpectrumProfileModeLineColor the spectrum profile mode line color
*/
public void addMirroredSpectrum(double[] aXAxisData, double[] aYAxisData, double aPrecursorMZ, String aPrecursorCharge, String aFileName, boolean aProfileMode,
Color aSpectrumPeakColor, Color aSpectrumProfileModeLineColor) {
iPrecursorMZMirroredSpectrum = aPrecursorMZ;
iPrecursorChargeMirorredSpectrum = aPrecursorCharge;
iFilenameMirrorredSpectrum = aFileName;
processMirroredXAndYData(aXAxisData, aYAxisData, aSpectrumPeakColor, aSpectrumProfileModeLineColor);
if (aProfileMode) {
this.currentGraphicsPanelType = GraphicsPanelType.profileSpectrum;
} else {
this.currentGraphicsPanelType = GraphicsPanelType.centroidSpectrum;
}
this.showFileName = false;
this.showPrecursorDetails = false;
this.showResolution = false;
this.yAxisZoomExcludesBackgroundPeaks = false;
this.yDataIsPositive = false;
}
/**
* Adds an additional spectrum dataset to be displayed in the same Spectrum
* Panel. Remember to use different colors for the different datasets.
*
* @param aXAxisData double[] with all the x-axis values.
* @param aYAxisData double[] with all the y-axis values
* @param dataPointAndLineColor the color to use for the data points and
* lines
* @param areaUnderCurveColor the color to use for the area under the curve
*/
public void addAdditionalDataset(double[] aXAxisData, double[] aYAxisData, Color dataPointAndLineColor, Color areaUnderCurveColor) {
processXAndYData(aXAxisData, aYAxisData, dataPointAndLineColor, areaUnderCurveColor);
this.showFileName = false;
this.showPrecursorDetails = false;
this.showResolution = false;
}
/**
* Adds an additional mirrored spectrum dataset to be displayed in the same
* Spectrum Panel. Remember to use different colors for the different
* datasets.
*
* @param aXAxisData double[] with all the x-axis values.
* @param aYAxisData double[] with all the y-axis values
* @param dataPointAndLineColor the color to use for the data points and
* lines
* @param areaUnderCurveColor the color to use for the area under the curve
*/
public void addAdditionalMirroredDataset(double[] aXAxisData, double[] aYAxisData, Color dataPointAndLineColor, Color areaUnderCurveColor) {
processMirroredXAndYData(aXAxisData, aYAxisData, dataPointAndLineColor, areaUnderCurveColor);
this.showFileName = false;
this.showPrecursorDetails = false;
this.showResolution = false;
}
/**
* Change the drawing type of the spectrum. Profile or centroid mode.
*
* @param aProfileMode if true, the spectrum is drawn in profile mode
*/
public void setProfileMode(boolean aProfileMode) {
if (aProfileMode) {
this.currentGraphicsPanelType = GraphicsPanelType.profileSpectrum;
} else {
this.currentGraphicsPanelType = GraphicsPanelType.centroidSpectrum;
}
}
/**
* Set the default spectrum peak color. (Note that this only has an impact
* on the first spectrum added. For additional spectra or mirrored spectra
* set the color in the given constructor.)
*
* @param aSpectrumPeakColor the color to set
*/
public void setSpectrumPeakColor(Color aSpectrumPeakColor) {
this.spectrumPeakColor = aSpectrumPeakColor;
}
/**
* Set the default spectrum profile mode color. (Note that this only has an
* impact on the first spectrum added. For additional spectra or mirrored
* spectra set the color in the given constructor.)
*
* @param aSpectrumProfileModeLineColor the color to set
*/
public void setSpectrumProfileModeLineColor(Color aSpectrumProfileModeLineColor) {
this.spectrumProfileModeLineColor = aSpectrumProfileModeLineColor;
}
/**
* If true only the annotated peaks will be drawn. The default value is
* false, and result in all peaks being drawn. Note that this setting is
* ignored when in profile mode!
*
* @param aAnnotatedPeaks if true only the annotated peaks will be drawn
*/
public void showAnnotatedPeaksOnly(boolean aAnnotatedPeaks) {
this.showAllPeaks = !aAnnotatedPeaks;
}
/**
* This method initializes a SpectrumPanel based on the spectrum information
* in the specified SpectrumFile.
*
* @param aSpecFile SpectrumFile with the information about masses and
* intensities that will be copied here. Note that mass-sorting will take
* place in this step as well.
*/
public void setSpectrumFile(SpectrumFile aSpecFile) {
this.processSpectrumFile(aSpecFile, spectrumPeakColor, spectrumProfileModeLineColor);
}
/**
* This method reads the peaks and their intensities from the specified
* SpectrumFile and stores these internally for drawing. The masses are
* sorted in this step.
*
* @param aSpecFile SpectrumFile from which the peaks and intensities will
* be copied.
* @param dataPointAndLineColor the color to use for the data points and
* line
* @param areaUnderCurveColor the color to use for the area under the curve
*/
private void processSpectrumFile(SpectrumFile aSpecFile, Color dataPointAndLineColor, Color areaUnderCurveColor) {
if (dataSetCounter == 0) {
iXAxisData = new ArrayList<double[]>();
iYAxisData = new ArrayList<double[]>();
}
iDataPointAndLineColor.add(dataPointAndLineColor);
iAreaUnderCurveColor.add(areaUnderCurveColor);
HashMap peaks = aSpecFile.getPeaks();
iXAxisData.add(new double[peaks.size()]);
iYAxisData.add(new double[peaks.size()]);
iFilename = aSpecFile.getFilename();
// Maximum intensity of the peaks.
double maxInt = 0.0;
// TreeSets are sorted.
TreeSet masses = new TreeSet(peaks.keySet());
Iterator iter = masses.iterator();
int count = 0;
while (iter.hasNext()) {
Double key = (Double) iter.next();
double mass = key.doubleValue();
double intensity = ((Double) peaks.get(key)).doubleValue();
if (intensity > maxInt) {
maxInt = intensity;
}
iXAxisData.get(dataSetCounter)[count] = mass;
iYAxisData.get(dataSetCounter)[count] = intensity;
count++;
}
if (iXAxisStartAtZero) {
this.rescale(0.0, getMaxXAxisValue());
} else {
this.rescale(getMinXAxisValue(), getMaxXAxisValue());
}
this.iPrecursorMZ = aSpecFile.getPrecursorMZ();
int liTemp = aSpecFile.getCharge();
if (liTemp == 0) {
iPrecursorCharge = "?";
} else {
iPrecursorCharge = Integer.toString(liTemp);
iPrecursorCharge += (liTemp > 0 ? "+" : "-");
}
dataSetCounter++;
}
/**
* Returns the peak color to be used for the given peak label. The colors
* used are based on the color coding used in MascotDatfile.
*
* @deprecated it is advised to use methods based on the ion type rather
* than on the peak label
* @param peakLabel the peak label
* @return the peak color
*/
public static Color determineColorOfPeak(String peakLabel) {
Color currentColor = Color.GRAY;
if (peakLabel.startsWith("a")) {
// turquoise
currentColor = new Color(153, 0, 0);
if (peakLabel.lastIndexOf("H2O") != -1 || peakLabel.lastIndexOf("H20") != -1) {
// light purple-blue
currentColor = new Color(171, 161, 255);
} else if (peakLabel.lastIndexOf("NH3") != -1) {
// ugly purple pink
currentColor = new Color(248, 151, 202);
}
} else if (peakLabel.startsWith("b")) {
// dark blue
currentColor = new Color(0, 0, 255);
if (peakLabel.lastIndexOf("H2O") != -1 || peakLabel.lastIndexOf("H20") != -1) {
// nice blue
currentColor = new Color(0, 125, 200);
} else if (peakLabel.lastIndexOf("NH3") != -1) {
// another purple
currentColor = new Color(153, 0, 255);
}
} else if (peakLabel.startsWith("c")) {
// purple blue
currentColor = new Color(188, 0, 255); // ToDo: no colors for H2O and NH3??
} else if (peakLabel.startsWith("x")) {
// green
currentColor = new Color(78, 200, 0); // ToDo: no colors for H2O and NH3??
} else if (peakLabel.startsWith("y")) {
// black
currentColor = new Color(0, 0, 0);
if (peakLabel.lastIndexOf("H2O") != -1 || peakLabel.lastIndexOf("H20") != -1) {
// navy blue
currentColor = new Color(0, 70, 135);
} else if (peakLabel.lastIndexOf("NH3") != -1) {
// another purple
currentColor = new Color(155, 0, 155);
}
} else if (peakLabel.startsWith("z")) {
// dark green
currentColor = new Color(64, 179, 0); // ToDo: no colors for H2O and NH3??
} else if (peakLabel.startsWith("Prec") || peakLabel.startsWith("MH")) { // precursor
// red
currentColor = Color.gray; // Color.red is used in MascotDatFile
} else if (peakLabel.startsWith("i")) { // immonimum ion
// grey
currentColor = Color.gray;
}
return currentColor;
}
/**
* Filters the annotations and returns the annotations matching the
* currently selected types.
*
* @deprecated don't use method based on the peak labels but on the data
* type
* @param annotations the annotations to be filtered, the annotations are
* assumed to have the following form: ion type + [ion number] + [charge] +
* [neutral loss]
* @param iontypes the fragment ion types to include, assumed to be one of
* the Ion types, e.g, IonType.PeptideFragmentIon >
* PeptideFragmentIon.B_ION
* @param neutralLosses list of neutral losses to display
* @param singleChargeSelected if singly charged fragments are to be
* included
* @param doubleChargeSelected if double charged fragments are to be
* included
* @param moreThanTwoChargesSelected if fragments with more than two charges
* are to be included
* @return the filtered annotations
*/
public static Vector<SpectrumAnnotation> filterAnnotations(
Vector<SpectrumAnnotation> annotations,
HashMap<Ion.IonType, ArrayList<Integer>> iontypes,
ArrayList<NeutralLoss> neutralLosses,
boolean singleChargeSelected,
boolean doubleChargeSelected,
boolean moreThanTwoChargesSelected) {
Vector<SpectrumAnnotation> filteredAnnotations = new Vector();
for (SpectrumAnnotation annotation : annotations) {
String currentLabel = annotation.getLabel();
boolean useAnnotation = false;
// check ion type
if (currentLabel.startsWith("a")) {
if (iontypes.containsKey(Ion.IonType.PEPTIDE_FRAGMENT_ION)
&& iontypes.get(Ion.IonType.PEPTIDE_FRAGMENT_ION).contains(PeptideFragmentIon.A_ION)) {
useAnnotation = true;
}
} else if (currentLabel.startsWith("b")) {
if (iontypes.containsKey(Ion.IonType.PEPTIDE_FRAGMENT_ION)
&& iontypes.get(Ion.IonType.PEPTIDE_FRAGMENT_ION).contains(PeptideFragmentIon.B_ION)) {
useAnnotation = true;
}
} else if (currentLabel.startsWith("c")) {
if (iontypes.containsKey(Ion.IonType.PEPTIDE_FRAGMENT_ION)
&& iontypes.get(Ion.IonType.PEPTIDE_FRAGMENT_ION).contains(PeptideFragmentIon.C_ION)) {
useAnnotation = true;
}
} else if (currentLabel.startsWith("x")) {
if (iontypes.containsKey(Ion.IonType.PEPTIDE_FRAGMENT_ION)
&& iontypes.get(Ion.IonType.PEPTIDE_FRAGMENT_ION).contains(PeptideFragmentIon.X_ION)) {
useAnnotation = true;
}
} else if (currentLabel.startsWith("y")) {
if (iontypes.containsKey(Ion.IonType.PEPTIDE_FRAGMENT_ION)
&& iontypes.get(Ion.IonType.PEPTIDE_FRAGMENT_ION).contains(PeptideFragmentIon.Y_ION)) {
useAnnotation = true;
}
} else if (currentLabel.startsWith("z")) {
if (iontypes.containsKey(Ion.IonType.PEPTIDE_FRAGMENT_ION)
&& iontypes.get(Ion.IonType.PEPTIDE_FRAGMENT_ION).contains(PeptideFragmentIon.Z_ION)) {
useAnnotation = true;
}
} else { // other
if (iontypes.containsKey(Ion.IonType.IMMONIUM_ION)
|| iontypes.containsKey(Ion.IonType.PRECURSOR_ION)
|| iontypes.containsKey(Ion.IonType.REPORTER_ION)
|| iontypes.containsKey(Ion.IonType.RELATED_ION)) {
useAnnotation = true;
}
}
// check neutral losses
if (useAnnotation) {
boolean h2oLossSelected = false;
boolean nh3LossSelected = false;
boolean phosphoLossSelected = false;
boolean moxLossSelected = false;
for (NeutralLoss neutralLoss : neutralLosses) {
if (neutralLoss.isSameAs(NeutralLoss.H2O)) {
h2oLossSelected = true;
} else if (neutralLoss.isSameAs(NeutralLoss.NH3)) {
nh3LossSelected = true;
} else if (neutralLoss.isSameAs(NeutralLoss.H3PO4)
|| neutralLoss.isSameAs(NeutralLoss.HPO3)) {
phosphoLossSelected = true;
} else if (neutralLoss.isSameAs(NeutralLoss.CH4OS)) {
moxLossSelected = true;
}
}
if (currentLabel.lastIndexOf("-H2O") != -1 || currentLabel.lastIndexOf("-H20") != -1) {
if (!h2oLossSelected) {
useAnnotation = false;
}
}
if (currentLabel.lastIndexOf("-NH3") != -1) {
if (!nh3LossSelected) {
useAnnotation = false;
}
}
if (currentLabel.lastIndexOf("-H3PO4") != -1
|| currentLabel.lastIndexOf("-HPO3") != -1) {
if (!phosphoLossSelected) {
useAnnotation = false;
}
}
if (currentLabel.lastIndexOf("-CH4OS") != -1) {
if (!moxLossSelected) {
useAnnotation = false;
}
}
}
// check ion charge
if (useAnnotation) {
if (currentLabel.lastIndexOf("+") == -1) {
// test needed to be able to show ions in the "other" group
if (currentLabel.startsWith("a") || currentLabel.startsWith("b") || currentLabel.startsWith("c")
|| currentLabel.startsWith("x") || currentLabel.startsWith("y") || currentLabel.startsWith("z")) {
if (!singleChargeSelected) {
useAnnotation = false;
}
}
} else if (currentLabel.lastIndexOf("+++") != -1) {
if (!moreThanTwoChargesSelected) {
useAnnotation = false;
}
} else if (currentLabel.lastIndexOf("++") != -1) {
if (!doubleChargeSelected) {
useAnnotation = false;
}
}
}
if (useAnnotation) {
filteredAnnotations.add(annotation);
}
}
return filteredAnnotations;
}
/**
* Sets an annotation color for the given ion.
*
* @param ion the ion
* @param color the new color
*/
public static void setIonColor(Ion ion, Color color) {
if (!colorMap.containsKey(ion.getType())) {
colorMap.put(ion.getType(), new HashMap<Integer, HashMap<String, Color>>());
}
if (!colorMap.get(ion.getType()).containsKey(ion.getSubType())) {
colorMap.get(ion.getType()).put(ion.getSubType(), new HashMap<String, Color>());
}
colorMap.get(ion.getType()).get(ion.getSubType()).put(ion.getNeutralLossesAsString(), color);
}
/**
* Returns the peak color to be used for the given peak label according to
* the color map. If not implemented returns the default color.
*
* @param ion the ion
* @param isSpectrum if true, the special spectrum color is used for the
* y-ion
* @return the peak color
*/
public static Color determineFragmentIonColor(Ion ion, boolean isSpectrum) {
if (colorMap.containsKey(ion.getType())
&& colorMap.get(ion.getType()).containsKey(ion.getSubType())
&& colorMap.get(ion.getType()).get(ion.getSubType()).containsKey(ion.getNeutralLossesAsString())) {
return colorMap.get(ion.getType()).get(ion.getSubType()).get(ion.getNeutralLossesAsString());
}
return determineDefaultFragmentIonColor(ion, isSpectrum);
}
/**
* Returns the peak color to be used for the given peak label. The colors
* used are based on the color coding used in MascotDatfile.
*
* @param ion the ion
* @param isSpectrum if true, the special spectrum color is used for the
* y-ion
* @return the peak color
*/
public static Color determineDefaultFragmentIonColor(Ion ion, boolean isSpectrum) {
switch (ion.getType()) {
case PEPTIDE_FRAGMENT_ION:
case TAG_FRAGMENT_ION:
switch (ion.getSubType()) {
case PeptideFragmentIon.A_ION:
if (ion.hasNeutralLosses()) {
if (ion.getNeutralLosses().size() == 1) {
NeutralLoss neutralLoss = ion.getNeutralLosses().get(0);
if (neutralLoss.isSameAs(NeutralLoss.H2O)) {
// light purple-blue
return new Color(171, 161, 255);
} else if (neutralLoss.isSameAs(NeutralLoss.NH3)) {
// ugly purple pink
return new Color(248, 151, 202);
} else if (neutralLoss.isSameAs(NeutralLoss.H3PO4)
|| neutralLoss.isSameAs(NeutralLoss.HPO3)) {
return Color.BLACK; // @TODO: black can _not_ be used here!!
}
} else if (ion.getNeutralLosses().size() > 1) {
return Color.GRAY;
}
}
// turquoise
return new Color(153, 0, 0);
case PeptideFragmentIon.B_ION:
if (ion.hasNeutralLosses()) {
if (ion.getNeutralLosses().size() == 1) {
NeutralLoss neutralLoss = ion.getNeutralLosses().get(0);
if (neutralLoss.isSameAs(NeutralLoss.H2O)) {
// nice blue
return new Color(0, 125, 200);
} else if (neutralLoss.isSameAs(NeutralLoss.NH3)) {
// another purple
return new Color(153, 0, 255);
} else if (neutralLoss.isSameAs(NeutralLoss.H3PO4)
|| neutralLoss.isSameAs(NeutralLoss.HPO3)) {
return Color.BLACK; // @TODO: black can _not_ be used here!!
}
} else if (ion.getNeutralLosses().size() > 1) {
return Color.GRAY;
}
}
// dark blue
return new Color(0, 0, 255);
case PeptideFragmentIon.C_ION:
if (ion.hasNeutralLosses()) {
if (ion.getNeutralLosses().size() == 1) {
NeutralLoss neutralLoss = ion.getNeutralLosses().get(0);
if (neutralLoss.isSameAs(NeutralLoss.H2O)) {
// ??
return new Color(188, 150, 255);
} else if (neutralLoss.isSameAs(NeutralLoss.NH3)) {
// ??
return new Color(255, 0, 255);
} else if (neutralLoss.isSameAs(NeutralLoss.H3PO4)
|| neutralLoss.isSameAs(NeutralLoss.HPO3)) {
return Color.BLACK; // @TODO: black can _not_ be used here!!
}
} else if (ion.getNeutralLosses().size() > 1) {
return Color.GRAY;
}
}
// purple blue
return new Color(188, 0, 255);
case PeptideFragmentIon.X_ION:
if (ion.hasNeutralLosses()) {
if (ion.getNeutralLosses().size() == 1) {
NeutralLoss neutralLoss = ion.getNeutralLosses().get(0);
if (neutralLoss.isSameAs(NeutralLoss.H2O)) {
// ??
return new Color(78, 200, 150);
} else if (neutralLoss.isSameAs(NeutralLoss.NH3)) {
// ??
return new Color(255, 200, 255);
} else if (neutralLoss.isSameAs(NeutralLoss.H3PO4)
|| neutralLoss.isSameAs(NeutralLoss.HPO3)) {
return Color.BLACK; // @TODO: black can _not_ be used here!!
}
} else if (ion.getNeutralLosses().size() > 1) {
return Color.GRAY;
}
}
// green
return new Color(78, 200, 0);
case PeptideFragmentIon.Y_ION:
if (ion.hasNeutralLosses()) {
if (ion.getNeutralLosses().size() == 1) {
NeutralLoss neutralLoss = ion.getNeutralLosses().get(0);
if (neutralLoss.isSameAs(NeutralLoss.H2O)) {
if (isSpectrum) {
// navy blue
return new Color(0, 70, 135);
} else {
// orange
return new Color(255, 150, 0);
}
} else if (neutralLoss.isSameAs(NeutralLoss.NH3)) {
if (isSpectrum) {
// another purple
return new Color(155, 0, 155);
} else {
// pink
return new Color(255, 0, 150);
}
} else if (neutralLoss.isSameAs(NeutralLoss.H3PO4)
|| neutralLoss.isSameAs(NeutralLoss.HPO3)) {
return Color.BLACK; // @TODO: black can _not_ be used here!!
}
} else if (ion.getNeutralLosses().size() > 1) {
return Color.GRAY;
}
}
if (isSpectrum) {
// black
return Color.BLACK; // special case for spectra, as the default peak color is red...
} else {
// red
return new Color(255, 0, 0);
}
case PeptideFragmentIon.Z_ION:
if (ion.hasNeutralLosses()) {
if (ion.getNeutralLosses().size() == 1) {
NeutralLoss neutralLoss = ion.getNeutralLosses().get(0);
if (neutralLoss.isSameAs(NeutralLoss.H2O)) {
// ??
return new Color(64, 179, 150);
} else if (neutralLoss.isSameAs(NeutralLoss.NH3)) {
// ??
return new Color(255, 179, 150);
} else if (neutralLoss.isSameAs(NeutralLoss.H3PO4)
|| neutralLoss.isSameAs(NeutralLoss.HPO3)) {
return Color.BLACK; // @TODO: black can _not_ be used here!!
}
} else if (ion.getNeutralLosses().size() > 1) {
return Color.GRAY;
}
}
// dark green
return new Color(64, 179, 0);
default:
return Color.GRAY;
}
case PRECURSOR_ION:
return Color.GRAY;
case IMMONIUM_ION:
return Color.GRAY;
case REPORTER_ION:
return Color.ORANGE;
case RELATED_ION:
return Color.GRAY;
default:
return Color.GRAY;
}
}
/**
* Returns the color to use for the given fragment ion label.
*
* @deprecated use the method based on the Ion class instead
* @param seriesLabel the series label
* @return the fragment ion color
*/
public static Color determineFragmentIonColor(String seriesLabel) {
Color currentColor = Color.GRAY;
if (seriesLabel.startsWith("a")) {
// turquoise
currentColor = new Color(153, 0, 0);
if (seriesLabel.lastIndexOf("H2O") != -1 || seriesLabel.lastIndexOf("H20") != -1) {
// light purple-blue
currentColor = new Color(171, 161, 255);
} else if (seriesLabel.lastIndexOf("NH3") != -1) {
// ugly purple pink
currentColor = new Color(248, 151, 202);
}
// change color slightly if a double charge is detected
if (seriesLabel.lastIndexOf("++") != -1) {
currentColor = new Color(currentColor.getRed() - 100, currentColor.getGreen(), currentColor.getBlue());
}
} else if (seriesLabel.startsWith("b")) {
// dark blue
currentColor = new Color(0, 0, 255);
// change color slightly if a neutral loss is detected
if (seriesLabel.lastIndexOf("H2O") != -1 || seriesLabel.lastIndexOf("H20") != -1) {
currentColor = new Color(0, 150, 255);
} else if (seriesLabel.lastIndexOf("NH3") != -1 || seriesLabel.equalsIgnoreCase("b ions - mod.")) {
currentColor = new Color(150, 0, 255);
}
// change color slightly if a double charge is detected
if (seriesLabel.lastIndexOf("++") != -1) {
currentColor = new Color(currentColor.getRed(), currentColor.getGreen(), currentColor.getBlue() - 100);
}
} else if (seriesLabel.startsWith("c")) {
// purple blue
currentColor = new Color(188, 0, 255);
// change color slightly if a neutral loss is detected
if (seriesLabel.lastIndexOf("H2O") != -1 || seriesLabel.lastIndexOf("H20") != -1) {
currentColor = new Color(188, 150, 255);
} else if (seriesLabel.lastIndexOf("NH3") != -1) {
currentColor = new Color(255, 0, 255);
}
// change color slightly if a double charge is detected
if (seriesLabel.lastIndexOf("++") != -1) {
currentColor = new Color(currentColor.getRed(), currentColor.getGreen(), currentColor.getBlue() - 100);
}
} else if (seriesLabel.startsWith("x")) {
// green
currentColor = new Color(78, 200, 0);
// change color slightly if a neutral loss is detected
if (seriesLabel.lastIndexOf("H2O") != -1 || seriesLabel.lastIndexOf("H20") != -1) {
currentColor = new Color(78, 200, 150);
} else if (seriesLabel.lastIndexOf("NH3") != -1) {
currentColor = new Color(255, 200, 255);
}
// change color slightly if a double charge is detected
if (seriesLabel.lastIndexOf("++") != -1) {
currentColor = new Color(currentColor.getRed(), currentColor.getGreen() - 100, currentColor.getBlue());
}
} else if (seriesLabel.startsWith("y")) {
// red
currentColor = new Color(255, 0, 0);
// change color slightly if a neutral loss is detected
if (seriesLabel.lastIndexOf("H2O") != -1 || seriesLabel.lastIndexOf("H20") != -1) {
currentColor = new Color(255, 150, 0);
} else if (seriesLabel.lastIndexOf("NH3") != -1 || seriesLabel.equalsIgnoreCase("y ions - mod.")) {
currentColor = new Color(255, 0, 150);
}
// change color slightly if a double charge is detected
if (seriesLabel.lastIndexOf("++") != -1) {
currentColor = new Color(currentColor.getRed() - 100, currentColor.getGreen(), currentColor.getBlue());
}
} else if (seriesLabel.startsWith("z")) {
// dark green
currentColor = new Color(64, 179, 0);
// change color slightly if a neutral loss is detected
if (seriesLabel.lastIndexOf("H2O") != -1 || seriesLabel.lastIndexOf("H20") != -1) {
currentColor = new Color(64, 179, 150);
} else if (seriesLabel.lastIndexOf("NH3") != -1) {
currentColor = new Color(255, 179, 150);
}
// change color slightly if a double charge is detected
if (seriesLabel.lastIndexOf("++") != -1) {
currentColor = new Color(currentColor.getRed(), currentColor.getGreen() - 100, currentColor.getBlue());
}
} else if (seriesLabel.startsWith("iTRAQ") || seriesLabel.startsWith("TMT")) {
return Color.ORANGE;
}
return currentColor;
}
/**
* Add reference areas annotating the de novo tags, using default percent
* height of 0.9 for the forward ions and 1.0 for the reverse ions default
* alpha levels of 0.2. Fixed PTMs are not annotated.
*
* @param currentPeptide the current peptide sequence
* @param annotations the current fragment ion annotations
* @param aForwardIon the forward de novo sequencing fragment ion type,
* i.e., PeptideFragmentIon.A_ION, PeptideFragmentIon.B_ION or
* PeptideFragmentIon.C_ION
* @param aRewindIon the reverse de novo sequencing fragment ion type, i.e.,
* PeptideFragmentIon.X_ION, PeptideFragmentIon.Y_ION or
* PeptideFragmentIon.Z_ION
* @param aDeNovoCharge the de novo sequencing charge
* @param showForwardTags if true, the forward de novo sequencing tags are
* displayed
* @param showRewindTags if true, the reverse de novo sequencing tags are
* displayed
* @param mirrored if true the annotation is for the mirrored spectrum
*/
public void addAutomaticDeNovoSequencing(
Peptide currentPeptide, ArrayList<IonMatch> annotations,
int aForwardIon, int aRewindIon, int aDeNovoCharge,
boolean showForwardTags, boolean showRewindTags, boolean mirrored) {
addAutomaticDeNovoSequencing(currentPeptide, annotations, aForwardIon, aRewindIon, aDeNovoCharge, showForwardTags, showRewindTags,
0.9, 1.0, 0.2f, 0.2f, null, true, mirrored);
}
/**
* Add reference areas annotating the de novo tags, using default alpha
* levels of 0.2. Fixed PTMs are not annotated.
*
* @param currentPeptide the current peptide sequence
* @param annotations the current fragment ion annotations
* @param aForwardIon the forward de novo sequencing fragment ion type,
* i.e., PeptideFragmentIon.A_ION, PeptideFragmentIon.B_ION or
* PeptideFragmentIon.C_ION
* @param aRewindIon the reverse de novo sequencing fragment ion type, i.e.,
* PeptideFragmentIon.X_ION, PeptideFragmentIon.Y_ION or
* PeptideFragmentIon.Z_ION
* @param aDeNovoCharge the de novo sequencing charge
* @param showForwardTags if true, the forward de novo sequencing tags are
* displayed
* @param showRewindTags if true, the reverse de novo sequencing tags are
* displayed
* @param forwardIonPercentHeight the percent height of the forward ion
* annotation [0-1]
* @param rewindIonPercentHeight the percent height of the reverse ion
* annotation [0-1]
* @param mirrored if true the annotation is for the mirrored spectrum
*/
public void addAutomaticDeNovoSequencing(
Peptide currentPeptide, ArrayList<IonMatch> annotations,
int aForwardIon, int aRewindIon, int aDeNovoCharge,
boolean showForwardTags, boolean showRewindTags,
double forwardIonPercentHeight, double rewindIonPercentHeight, boolean mirrored) {
addAutomaticDeNovoSequencing(currentPeptide, annotations, aForwardIon, aRewindIon, aDeNovoCharge, showForwardTags, showRewindTags,
forwardIonPercentHeight, rewindIonPercentHeight, 0.2f, 0.2f, null, true, mirrored);
}
/**
* Add reference areas annotating the de novo tags, using default alpha
* levels of 0.2.
*
* @param currentPeptide the current peptide sequence
* @param annotations the current fragment ion annotations
* @param aForwardIon the forward de novo sequencing fragment ion type,
* i.e., PeptideFragmentIon.A_ION, PeptideFragmentIon.B_ION or
* PeptideFragmentIon.C_ION
* @param aRewindIon the reverse de novo sequencing fragment ion type, i.e.,
* PeptideFragmentIon.X_ION, PeptideFragmentIon.Y_ION or
* PeptideFragmentIon.Z_ION
* @param aDeNovoCharge the de novo sequencing charge
* @param showForwardTags if true, the forward de novo sequencing tags are
* displayed
* @param showRewindTags if true, the reverse de novo sequencing tags are
* displayed
* @param forwardIonPercentHeight the percent height of the forward ion
* annotation [0-1]
* @param rewindIonPercentHeight the percent height of the reverse ion
* annotation [0-1]
* @param excludeFixedPtms are fixed PTMs to be annotated?
* @param mirrored if true the annotation is for the mirrored spectrum
*/
public void addAutomaticDeNovoSequencing(
Peptide currentPeptide, ArrayList<IonMatch> annotations,
int aForwardIon, int aRewindIon, int aDeNovoCharge,
boolean showForwardTags, boolean showRewindTags,
double forwardIonPercentHeight, double rewindIonPercentHeight, boolean excludeFixedPtms, boolean mirrored) {
addAutomaticDeNovoSequencing(currentPeptide, annotations, aForwardIon, aRewindIon, aDeNovoCharge, showForwardTags, showRewindTags,
forwardIonPercentHeight, rewindIonPercentHeight, 0.2f, 0.2f, null, excludeFixedPtms, mirrored);
}
/**
* Add reference areas annotating the de novo tags, using default percent
* height of 0.9 for the forward ions and 1.0 for the reverse ions default
* alpha levels of 0.2. Fixed PTMs are not annotated.
*
* @param tag the current tag sequence
* @param annotations the current fragment ion annotations
* @param aForwardIon the forward de novo sequencing fragment ion type,
* i.e., PeptideFragmentIon.A_ION, PeptideFragmentIon.B_ION or
* PeptideFragmentIon.C_ION
* @param aRewindIon the reverse de novo sequencing fragment ion type, i.e.,
* PeptideFragmentIon.X_ION, PeptideFragmentIon.Y_ION or
* PeptideFragmentIon.Z_ION
* @param aDeNovoCharge the de novo sequencing charge
* @param showForwardTags if true, the forward de novo sequencing tags are
* displayed
* @param showRewindTags if true, the reverse de novo sequencing tags are
* displayed
* @param mirrored if true the annotation is for the mirrored spectrum
*/
public void addAutomaticDeNovoSequencing(
Tag tag, ArrayList<IonMatch> annotations,
int aForwardIon, int aRewindIon, int aDeNovoCharge,
boolean showForwardTags, boolean showRewindTags, boolean mirrored) {
addAutomaticDeNovoSequencing(tag, annotations, aForwardIon, aRewindIon, aDeNovoCharge, showForwardTags, showRewindTags,
0.9, 1.0, 0.2f, 0.2f, null, true, mirrored);
}
/**
* Add reference areas annotating the de novo tags, using default alpha
* levels of 0.2. Fixed PTMs are not annotated.
*
* @param tag the current tag sequence
* @param annotations the current fragment ion annotations
* @param aForwardIon the forward de novo sequencing fragment ion type,
* i.e., PeptideFragmentIon.A_ION, PeptideFragmentIon.B_ION or
* PeptideFragmentIon.C_ION
* @param aRewindIon the reverse de novo sequencing fragment ion type, i.e.,
* PeptideFragmentIon.X_ION, PeptideFragmentIon.Y_ION or
* PeptideFragmentIon.Z_ION
* @param aDeNovoCharge the de novo sequencing charge
* @param showForwardTags if true, the forward de novo sequencing tags are
* displayed
* @param showRewindTags if true, the reverse de novo sequencing tags are
* displayed
* @param forwardIonPercentHeight the percent height of the forward ion
* annotation [0-1]
* @param rewindIonPercentHeight the percent height of the reverse ion
* annotation [0-1]
* @param mirrored if true the annotation is for the mirrored spectrum
*/
public void addAutomaticDeNovoSequencing(
Tag tag, ArrayList<IonMatch> annotations,
int aForwardIon, int aRewindIon, int aDeNovoCharge,
boolean showForwardTags, boolean showRewindTags,
double forwardIonPercentHeight, double rewindIonPercentHeight, boolean mirrored) {
addAutomaticDeNovoSequencing(tag, annotations, aForwardIon, aRewindIon, aDeNovoCharge, showForwardTags, showRewindTags,
forwardIonPercentHeight, rewindIonPercentHeight, 0.2f, 0.2f, null, true, mirrored);
}
/**
* Add reference areas annotating the de novo tags, using default alpha
* levels of 0.2.
*
* @param tag the current tag sequence
* @param annotations the current fragment ion annotations
* @param aForwardIon the forward de novo sequencing fragment ion type,
* i.e., PeptideFragmentIon.A_ION, PeptideFragmentIon.B_ION or
* PeptideFragmentIon.C_ION
* @param aRewindIon the reverse de novo sequencing fragment ion type, i.e.,
* PeptideFragmentIon.X_ION, PeptideFragmentIon.Y_ION or
* PeptideFragmentIon.Z_ION
* @param aDeNovoCharge the de novo sequencing charge
* @param showForwardTags if true, the forward de novo sequencing tags are
* displayed
* @param showRewindTags if true, the reverse de novo sequencing tags are
* displayed
* @param forwardIonPercentHeight the percent height of the forward ion
* annotation [0-1]
* @param rewindIonPercentHeight the percent height of the reverse ion
* annotation [0-1]
* @param alphaLevels the individual alpha levels, if set override
* forwardIonAlphaLevel and rewindIonAlphaLevel
* @param excludeFixedPtms are fixed PTMs to be annotated?
* @param mirrored if true the annotation is for the mirrored spectrum
*/
public void addAutomaticDeNovoSequencing(
Tag tag, ArrayList<IonMatch> annotations,
int aForwardIon, int aRewindIon, int aDeNovoCharge,
boolean showForwardTags, boolean showRewindTags,
double forwardIonPercentHeight, double rewindIonPercentHeight, ArrayList<float[]> alphaLevels, boolean excludeFixedPtms, boolean mirrored) {
addAutomaticDeNovoSequencing(tag, annotations, aForwardIon, aRewindIon, aDeNovoCharge, showForwardTags, showRewindTags,
forwardIonPercentHeight, rewindIonPercentHeight, 0.2f, 0.2f, alphaLevels, excludeFixedPtms, mirrored);
}
/**
* Add reference areas annotating the de novo tags.
*
* @param currentPeptide the current peptide sequence
* @param annotations the current fragment ion annotations
* @param aForwardIon the forward de novo sequencing fragment ion type,
* i.e., PeptideFragmentIon.A_ION, PeptideFragmentIon.B_ION or
* PeptideFragmentIon.C_ION
* @param aRewindIon the reverse de novo sequencing fragment ion type, i.e.,
* PeptideFragmentIon.X_ION, PeptideFragmentIon.Y_ION or
* PeptideFragmentIon.Z_ION
* @param aDeNovoCharge the de novo sequencing charge
* @param showForwardTags if true, the forward de novo sequencing tags are
* displayed
* @param showRewindTags if true, the reverse de novo sequencing tags are
* displayed
* @param forwardIonPercentHeight the percent height of the forward ion
* annotation [0-1]
* @param rewindIonPercentHeight the percent height of the reverse ion
* annotation [0-1]
* @param alphaLevels the individual alpha levels, if set override
* forwardIonAlphaLevel and rewindIonAlphaLevel
* @param excludeFixedPtms are fixed PTMs to be annotated?
* @param mirrored if true the annotation is for the mirrored spectrum
*/
public void addAutomaticDeNovoSequencing(
Peptide currentPeptide, ArrayList<IonMatch> annotations,
int aForwardIon, int aRewindIon, int aDeNovoCharge,
boolean showForwardTags, boolean showRewindTags,
double forwardIonPercentHeight, double rewindIonPercentHeight,
ArrayList<float[]> alphaLevels, boolean excludeFixedPtms, boolean mirrored) {
addAutomaticDeNovoSequencing(currentPeptide, annotations, aForwardIon, aRewindIon, aDeNovoCharge, showForwardTags, showRewindTags,
forwardIonPercentHeight, rewindIonPercentHeight, 0.2f, 0.2f, alphaLevels, excludeFixedPtms, mirrored);
}
/**
* Add reference areas annotating the de novo tags.
*
* @param currentPeptide the current peptide sequence
* @param annotations the current fragment ion annotations
* @param aForwardIon the forward de novo sequencing fragment ion type,
* i.e., PeptideFragmentIon.A_ION, PeptideFragmentIon.B_ION or
* PeptideFragmentIon.C_ION
* @param aRewindIon the reverse de novo sequencing fragment ion type, i.e.,
* PeptideFragmentIon.X_ION, PeptideFragmentIon.Y_ION or
* PeptideFragmentIon.Z_ION
* @param aDeNovoCharge the de novo sequencing charge
* @param showForwardTags if true, the forward de novo sequencing tags are
* displayed
* @param showRewindTags if true, the reverse de novo sequencing tags are
* displayed
* @param forwardIonPercentHeight the percent height of the forward ion
* annotation [0-1]
* @param rewindIonPercentHeight the percent height of the reverse ion
* annotation [0-1]
* @param forwardIonAlphaLevel alpha level of the forward ions
* @param rewindIonAlphaLevel alpha level of the reverse ions
* @param alphaLevels the individual alpha levels, if set override
* forwardIonAlphaLevel and rewindIonAlphaLevel
* @param excludeFixedPtms are fixed PTMs to be annotated?
* @param mirrored if true the annotation is for the mirrored spectrum
*/
public void addAutomaticDeNovoSequencing(
Peptide currentPeptide, ArrayList<IonMatch> annotations,
int aForwardIon, int aRewindIon, int aDeNovoCharge,
boolean showForwardTags, boolean showRewindTags,
double forwardIonPercentHeight, double rewindIonPercentHeight,
float forwardIonAlphaLevel, float rewindIonAlphaLevel, ArrayList<float[]> alphaLevels,
boolean excludeFixedPtms, boolean mirrored) {
int forwardIon = aForwardIon;
int reverseIon = aRewindIon;
int deNovoCharge = aDeNovoCharge;
IonMatch[] forwardIons = new IonMatch[currentPeptide.getSequence().length()];
IonMatch[] reverseIons = new IonMatch[currentPeptide.getSequence().length()];
// iterate the annotations and find the de novo tags
for (IonMatch tempMatch : annotations) {
if (tempMatch.ion.getType() == Ion.IonType.PEPTIDE_FRAGMENT_ION
&& !tempMatch.ion.hasNeutralLosses()
&& tempMatch.charge == deNovoCharge) {
PeptideFragmentIon fragmentIon = (PeptideFragmentIon) tempMatch.ion;
if (fragmentIon.getSubType() == forwardIon) {
forwardIons[fragmentIon.getNumber() - 1] = tempMatch;
} else if (fragmentIon.getSubType() == reverseIon) {
reverseIons[fragmentIon.getNumber() - 1] = tempMatch;
}
}
}
ArrayList<Integer> modifiedIndexes = currentPeptide.getModifiedIndexes(excludeFixedPtms);
// add reverse ion de novo tags (x, y or z)
if (showRewindTags) {
Color annotationColor = SpectrumPanel.determineFragmentIonColor(Ion.getGenericIon(Ion.IonType.PEPTIDE_FRAGMENT_ION, reverseIon), false);
for (int i = 1; i < reverseIons.length; i++) {
if (reverseIons[i] != null && reverseIons[i - 1] != null) {
String mod = "";
if (modifiedIndexes.contains(currentPeptide.getSequence().length() - i)) {
mod = "*";
}
float currentAlphaLevel = rewindIonAlphaLevel;
if (alphaLevels != null) {
currentAlphaLevel = alphaLevels.get(0)[currentPeptide.getSequence().length() - i];
}
addReferenceAreaXAxis(new ReferenceArea(
"r" + i + "_" + mirrored,
currentPeptide.getSequence().substring(currentPeptide.getSequence().length() - i - 1, currentPeptide.getSequence().length() - i) + mod,
reverseIons[i - 1].peak.mz, reverseIons[i].peak.mz, annotationColor, currentAlphaLevel, false, true, annotationColor, true,
Color.lightGray, 0.2f, rewindIonPercentHeight, !mirrored));
}
}
}
// add forward ion de novo tags (a, b or c)
if (showForwardTags) {
Color annotationColor = SpectrumPanel.determineFragmentIonColor(Ion.getGenericIon(Ion.IonType.PEPTIDE_FRAGMENT_ION, forwardIon), false);
for (int i = 1; i < forwardIons.length; i++) {
if (forwardIons[i] != null && forwardIons[i - 1] != null) {
String mod = "";
if (modifiedIndexes.contains(i + 1)) {
mod = "*";
}
float currentAlphaLevel = forwardIonAlphaLevel;
if (alphaLevels != null) {
currentAlphaLevel = alphaLevels.get(0)[i];
}
addReferenceAreaXAxis(new ReferenceArea(
"f" + i + "_" + mirrored,
currentPeptide.getSequence().substring(i, i + 1) + mod,
forwardIons[i - 1].peak.mz, forwardIons[i].peak.mz, annotationColor, currentAlphaLevel, false, true, annotationColor, true,
Color.lightGray, 0.2f, forwardIonPercentHeight, !mirrored));
}
}
}
}
/**
* Add reference areas annotating the de novo tags.
*
* @param tag the current tag sequence
* @param annotations the current fragment ion annotations
* @param aForwardIon the forward de novo sequencing fragment ion type,
* i.e., PeptideFragmentIon.A_ION, PeptideFragmentIon.B_ION or
* PeptideFragmentIon.C_ION
* @param aRewindIon the reverse de novo sequencing fragment ion type, i.e.,
* PeptideFragmentIon.X_ION, PeptideFragmentIon.Y_ION or
* PeptideFragmentIon.Z_ION
* @param aDeNovoCharge the de novo sequencing charge
* @param showForwardTags if true, the forward de novo sequencing tags are
* displayed
* @param showReverseTags if true, the reverse de novo sequencing tags are
* displayed
* @param forwardIonPercentHeight the percent height of the forward ion
* annotation [0-1]
* @param rewindIonPercentHeight the percent height of the reverse ion
* annotation [0-1]
* @param forwardIonAlphaLevel alpha level of the forward ions
* @param rewindIonAlphaLevel alpha level of the reverse ions
* @param alphaLevels the individual alpha levels, if set override
* forwardIonAlphaLevel and rewindIonAlphaLevel
* @param excludeFixedPtms are fixed PTMs to be annotated?
* @param mirrored if true the annotation is for the mirrored spectrum
*/
public void addAutomaticDeNovoSequencing(
Tag tag, ArrayList<IonMatch> annotations,
int aForwardIon, int aRewindIon, int aDeNovoCharge,
boolean showForwardTags, boolean showReverseTags,
double forwardIonPercentHeight, double rewindIonPercentHeight,
float forwardIonAlphaLevel, float rewindIonAlphaLevel, ArrayList<float[]> alphaLevels,
boolean excludeFixedPtms, boolean mirrored) {
int forwardIon = aForwardIon;
int rewindIon = aRewindIon;
int deNovoCharge = aDeNovoCharge;
// @TODO: include multiple ions
HashMap<Integer, IonMatch> forwardMap = new HashMap<Integer, IonMatch>();
HashMap<Integer, IonMatch> rewindMap = new HashMap<Integer, IonMatch>();
for (IonMatch ionMatch : annotations) {
if (ionMatch.ion.getType() == Ion.IonType.TAG_FRAGMENT_ION
&& !ionMatch.ion.hasNeutralLosses()
&& ionMatch.charge == deNovoCharge) {
TagFragmentIon fragmentIon = (TagFragmentIon) ionMatch.ion;
if (fragmentIon.getSubType() == forwardIon) {
forwardMap.put(fragmentIon.getSubNumber(), ionMatch);
} else if (fragmentIon.getSubType() == rewindIon) {
rewindMap.put(fragmentIon.getSubNumber(), ionMatch);
}
}
}
// add forward annotation
for (int tagCount = 0; tagCount < tag.getContent().size(); tagCount++) {
TagComponent tagComponent = tag.getContent().get(tagCount);
if (tagComponent instanceof AminoAcidPattern) {
AminoAcidPattern aminoAcidPattern = (AminoAcidPattern) tagComponent;
// add forward ion de novo tags (a, b or c)
if (showForwardTags) {
Color annotationColor = SpectrumPanel.determineFragmentIonColor(Ion.getGenericIon(Ion.IonType.PEPTIDE_FRAGMENT_ION, forwardIon), false);
for (int i = 0; i < aminoAcidPattern.length(); i++) {
IonMatch ionMatch1 = forwardMap.get(i);
IonMatch ionMatch2 = forwardMap.get(i + 1);
if (ionMatch1 != null && ionMatch2 != null) {
String mod = "";
ArrayList<ModificationMatch> modificationMatches = aminoAcidPattern.getModificationsAt(i + 1);
if (!modificationMatches.isEmpty()) {
mod = "*";
}
float currentAlphaLevel = forwardIonAlphaLevel;
if (alphaLevels != null) {
currentAlphaLevel = alphaLevels.get(tagCount)[i];
}
addReferenceAreaXAxis(new ReferenceArea(
"f" + i + "_" + mirrored,
aminoAcidPattern.asSequence(i) + mod,
ionMatch1.peak.mz, ionMatch2.peak.mz, annotationColor, currentAlphaLevel, false, true, annotationColor, true,
Color.lightGray, 0.2f, forwardIonPercentHeight, !mirrored));
}
}
}
} else if (tagComponent instanceof AminoAcidSequence) {
AminoAcidSequence aminoAcidSequence = (AminoAcidSequence) tagComponent;
// add forward ion de novo tags (a, b or c)
if (showForwardTags) {
Color annotationColor = SpectrumPanel.determineFragmentIonColor(Ion.getGenericIon(Ion.IonType.PEPTIDE_FRAGMENT_ION, forwardIon), false);
for (int i = 0; i < aminoAcidSequence.length(); i++) {
IonMatch ionMatch1 = forwardMap.get(i);
IonMatch ionMatch2 = forwardMap.get(i + 1);
if (ionMatch1 != null && ionMatch2 != null) {
String mod = "";
ArrayList<ModificationMatch> modificationMatches = aminoAcidSequence.getModificationsAt(i + 1);
if (!modificationMatches.isEmpty()) {
mod = "*";
}
float currentAlphaLevel = forwardIonAlphaLevel;
if (alphaLevels != null) {
currentAlphaLevel = alphaLevels.get(tagCount)[i];
}
addReferenceAreaXAxis(new ReferenceArea(
"f" + i + "_" + mirrored,
aminoAcidSequence.charAt(i) + mod,
ionMatch1.peak.mz, ionMatch2.peak.mz, annotationColor, currentAlphaLevel, false, true, annotationColor, true,
Color.lightGray, 0.2f, forwardIonPercentHeight, !mirrored));
}
}
}
} else if (tagComponent instanceof MassGap) {
// nothing to annotate here
} else {
throw new UnsupportedOperationException("Spectrum annotation not implemented for tag component " + tagComponent.getClass() + ".");
}
}
ArrayList<TagComponent> reversedTag = new ArrayList<TagComponent>(tag.getContent());
Collections.reverse(reversedTag);
// add reverse annotation
for (int tagCount = 0; tagCount < reversedTag.size(); tagCount++) {
TagComponent tagComponent = reversedTag.get(tagCount);
if (tagComponent instanceof AminoAcidPattern) {
AminoAcidPattern aminoAcidPattern = (AminoAcidPattern) tagComponent;
// add reverse ion de novo tags (x, y or z)
if (showReverseTags) {
Color annotationColor = SpectrumPanel.determineFragmentIonColor(Ion.getGenericIon(Ion.IonType.PEPTIDE_FRAGMENT_ION, rewindIon), false);
for (int i = 0; i < aminoAcidPattern.length(); i++) {
IonMatch ionMatch1 = rewindMap.get(i);
IonMatch ionMatch2 = rewindMap.get(i + 1);
if (ionMatch1 != null && ionMatch2 != null) {
int sequenceIndex = aminoAcidPattern.length() - i - 1;
String mod = "";
ArrayList<ModificationMatch> modificationMatches = aminoAcidPattern.getModificationsAt(sequenceIndex + 1);
if (!modificationMatches.isEmpty()) {
mod = "*";
}
float currentAlphaLevel = rewindIonAlphaLevel;
if (alphaLevels != null) {
currentAlphaLevel = alphaLevels.get(tagCount)[sequenceIndex];
}
addReferenceAreaXAxis(new ReferenceArea(
"r" + sequenceIndex + "_" + mirrored,
aminoAcidPattern.asSequence(sequenceIndex) + mod,
ionMatch1.peak.mz, ionMatch2.peak.mz, annotationColor, currentAlphaLevel, false, true, annotationColor, true,
Color.lightGray, 0.2f, rewindIonPercentHeight, !mirrored));
}
}
}
} else if (tagComponent instanceof AminoAcidSequence) {
AminoAcidSequence aminoAcidSequence = (AminoAcidSequence) tagComponent;
// add reverse ion de novo tags (x, y or z)
if (showReverseTags) {
Color annotationColor = SpectrumPanel.determineFragmentIonColor(Ion.getGenericIon(Ion.IonType.PEPTIDE_FRAGMENT_ION, rewindIon), false);
for (int i = 0; i < aminoAcidSequence.length(); i++) {
IonMatch ionMatch1 = rewindMap.get(i);
IonMatch ionMatch2 = rewindMap.get(i + 1);
if (ionMatch1 != null && ionMatch2 != null) {
int sequenceIndex = aminoAcidSequence.length() - i - 1;
String mod = "";
ArrayList<ModificationMatch> modificationMatches = aminoAcidSequence.getModificationsAt(sequenceIndex + 1);
if (!modificationMatches.isEmpty()) {
mod = "*";
}
float currentAlphaLevel = rewindIonAlphaLevel;
if (alphaLevels != null) {
currentAlphaLevel = alphaLevels.get(tagCount)[sequenceIndex];
}
addReferenceAreaXAxis(new ReferenceArea(
"r" + sequenceIndex + "_" + mirrored,
aminoAcidSequence.charAt(sequenceIndex) + mod,
ionMatch1.peak.mz, ionMatch2.peak.mz, annotationColor, currentAlphaLevel, false, true, annotationColor, true,
Color.lightGray, 0.2f, rewindIonPercentHeight, !mirrored));
}
}
}
} else if (tagComponent instanceof MassGap) {
// nothing to annotate here
} else {
throw new UnsupportedOperationException("Spectrum annotation not implemented for tag component " + tagComponent.getClass() + ".");
}
}
}
}