/*
* Copyright (c) 2003-2012 Fred Hutchinson Cancer Research Center
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.fhcrc.cpl.toolbox.proteomics.filehandler;
import org.apache.log4j.Logger;
import org.fhcrc.cpl.toolbox.Rounder;
import org.fhcrc.cpl.toolbox.filehandler.SimpleXMLStreamReader;
import org.fhcrc.cpl.toolbox.proteomics.Protein;
import org.fhcrc.cpl.toolbox.proteomics.MS2ModificationList;
import org.fhcrc.cpl.toolbox.proteomics.MS2Modification;
import org.fhcrc.cpl.toolbox.proteomics.ModifiedAminoAcid;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class PepXmlLoader extends MS2Loader
{
private PeptideProphetSummary _ppSummary;
private ArrayList<RelativeQuantAnalysisSummary> _quantSummaries = new ArrayList<RelativeQuantAnalysisSummary>();
public PepXmlLoader(File f, Logger log) throws FileNotFoundException, XMLStreamException
{
init(f, log);
readAnalysisSummaries();
}
// Read xpress, peptide prophet, etc. analysis summaries at the top of the file
// Starts at the beginning and ends on the first msms_run_summary tag
public void readAnalysisSummaries() throws XMLStreamException
{
while (_parser.hasNext())
{
_parser.next();
if (_parser.isStartElement())
{
String element = _parser.getLocalName();
if (element.equals("msms_run_summary"))
return;
if (element.equals("analysis_summary"))
{
String analysisType = _parser.getAttributeValue(null, "analysis");
if (analysisType.equals("peptideprophet"))
_ppSummary = PeptideProphetSummary.load(_parser);
else if (XPressHandler.analysisType.equals(analysisType))
_quantSummaries.add(XPressAnalysisSummary.load(_parser));
else if (Q3Handler.analysisType.equals(analysisType))
_quantSummaries.add(Q3AnalysisSummary.load(_parser));
}
}
}
}
public PeptideProphetSummary getPeptideProphetSummary()
{
return _ppSummary;
}
public List<RelativeQuantAnalysisSummary> getQuantSummaries()
{
return _quantSummaries;
}
public FractionIterator getFractionIterator()
{
return new FractionIterator();
}
public class FractionIterator implements Iterator<PepXmlFraction>
{
public boolean hasNext()
{
boolean hasNext = true;
// If we're not currently on the start of an msms_run_summary then attempt to skip to the next one
if (!_parser.isStartElement() || !"msms_run_summary".equals(_parser.getLocalName()))
{
try
{
hasNext = _parser.skipToStart("msms_run_summary");
}
catch (XMLStreamException e)
{
_log.error("XMLStreamException in hasNext()", e);
throw new RuntimeException("XMLStreamException in hasNext()", e);
}
}
return hasNext;
}
public PepXmlFraction next()
{
try
{
return PepXmlFraction.getNextFraction(_parser);
}
catch (XMLStreamException e)
{
_log.error("XMLStreamException in next()", e);
throw new RuntimeException("XMLStreamException in next()", e);
}
}
public void remove()
{
throw new UnsupportedOperationException();
}
}
public static class PepXmlFraction
{
private SimpleXMLStreamReader _parser;
private String _massSpecType = null;
private String _searchEngine = null;
private String _searchEnzyme = null;
//dhmay adding 2008/01/30
private int _searchConstraintMaxInternalCleavages;
private int _searchConstraintMinTermini;
private String _databaseLocalPath = null;
private String _dataBasename, _dataSuffix;
private String _spectrumPath = null;
private Float _importSpectraMinProbability = null;
private boolean _loadSpectra = true;
private MS2ModificationList _modifications = new MS2ModificationList();
public static PepXmlFraction getNextFraction(SimpleXMLStreamReader parser) throws XMLStreamException
{
PepXmlFraction fraction = new PepXmlFraction(parser);
fraction.assembleRunInfo();
return fraction;
}
private PepXmlFraction(SimpleXMLStreamReader parser)
{
_parser = parser;
}
// Pull run info together from the msms_run_summary and search_summary
// We start on an msms_run_summary tag
protected void assembleRunInfo() throws XMLStreamException
{
_massSpecType = null;
_searchEngine = null;
_searchEnzyme = null;
_databaseLocalPath = null;
handleMsMsRunSummary();
if (!_parser.skipToStart("search_summary"))
{
throw new XMLStreamException("No search_summary to skip to");
}
handleSearchSummary();
}
private void handleMsMsRunSummary()
{
String[] instrument = new String[]{
_parser.getAttributeValue(null, "msManufacturer"),
_parser.getAttributeValue(null, "msModel"),
};
_massSpecType = join(" ", instrument);
}
private boolean handleSearchSummary() throws XMLStreamException
{
boolean endOfSearchSummary = false;
while (!endOfSearchSummary)
{
if (_parser.isWhiteSpace() || XMLStreamReader.COMMENT == _parser.getEventType())
{
_parser.next();
continue;
}
String element = _parser.getLocalName();
if (_parser.isStartElement())
{
if (element.equals("search_query"))
endOfSearchSummary = true;
else if (element.equals("search_summary"))
{
_searchEngine = _parser.getAttributeValue(null, "search_engine");
_dataBasename = _parser.getAttributeValue(null, "base_name");
_dataSuffix = _parser.getAttributeValue(null, "out_data");
if (_dataSuffix == null)
_dataSuffix = "tgz";
else if (_dataSuffix.startsWith("."))
_dataSuffix = _dataSuffix.substring(1);
}
else if (element.equals("search_database"))
_databaseLocalPath = _parser.getAttributeValue(null, "local_path");
else if (element.equals("aminoacid_modification"))
handleModification(false);
else if (element.equals("terminal_modification"))
handleModification(true);
else if (element.equals("enzymatic_search_constraint"))
handleEnzymaticSearchConstraint();
else if (element.equals("parameter"))
{
String name = _parser.getAttributeValue(null, "name");
if ("spectrum, path".equals(name))
_spectrumPath = _parser.getAttributeValue(null, "value");
if ("pipeline, import spectra min probability".equals(name))
_importSpectraMinProbability = Float.parseFloat(_parser.getAttributeValue(null, "value"));
if ("pipeline, load spectra".equals(name) || "pipeline, import spectra".equals(name))
_loadSpectra = !"no".equalsIgnoreCase(_parser.getAttributeValue(null, "value"));
}
}
else
{
if (element.equals("search_summary"))
endOfSearchSummary = true;
}
if (!endOfSearchSummary)
_parser.next();
}
// Assign symbols to modifications that don't have them
_modifications.initializeSymbols();
// We should now have all the run info collected
return true;
}
/**
* Deal with both aminoacid and terminal modifications
* dhmay enhancing 7/21/2008 to deal with terminal
* @param isTerminal
*/
private void handleModification(boolean isTerminal)
{
MS2Modification mod = new MS2Modification();
if (isTerminal)
{
mod.setAminoAcid(_parser.getAttributeValue(null, "terminus"));
}
else
{
mod.setAminoAcid(_parser.getAttributeValue(null, "aminoacid"));
}
mod.setMassDiff(Float.parseFloat(_parser.getAttributeValue(null, "massdiff")));
mod.setVariable("Y".equals(_parser.getAttributeValue(null, "variable")));
mod.setMass(Float.parseFloat(_parser.getAttributeValue(null, "mass")));
if (mod.getVariable())
mod.setSymbol(_parser.getAttributeValue(null, "symbol"));
else
mod.setSymbol("?");
//System.err.println("new modification: " + mod);
_modifications.add(mod);
}
private void handleEnzymaticSearchConstraint()
{
_searchEnzyme = _parser.getAttributeValue(null, "enzyme");
String maxCleavagesString = _parser.getAttributeValue(null, "max_num_internal_cleavages");
if (maxCleavagesString != null)
_searchConstraintMaxInternalCleavages = Integer.parseInt(maxCleavagesString);
else
_searchConstraintMaxInternalCleavages = 0;
String minTerminiString = _parser.getAttributeValue(null, "min_number_termini");
if (minTerminiString != null)
_searchConstraintMinTermini = Integer.parseInt(minTerminiString);
else
_searchConstraintMinTermini = 0;
}
public String getMassSpecType()
{
return _massSpecType;
}
public List<MS2Modification> getModifications()
{
return _modifications;
}
public String getSearchEngine()
{
return _searchEngine;
}
public String getSearchEnzyme()
{
return _searchEnzyme;
}
public int getSearchConstraintMaxInternalCleavages()
{
return _searchConstraintMaxInternalCleavages;
}
public int getSearchConstraintMinTermini()
{
return _searchConstraintMinTermini;
}
public String getDataBasename()
{
return _dataBasename;
}
public String getDataSuffix()
{
return _dataSuffix;
}
public String getDatabaseLocalPath()
{
return _databaseLocalPath;
}
public String getSpectrumPath()
{
return _spectrumPath;
}
//The pepXML for sequest does not contain input.xml params.
public void setSpectrumPath(String spectrumPath)
{
this._spectrumPath = spectrumPath;
}
public boolean shouldLoadSpectra()
{
return _loadSpectra;
}
public Float getImportSpectraMinProbability()
{
return _importSpectraMinProbability;
}
public PeptideIterator getPeptideIterator()
{
return new PeptideIterator(_parser, _modifications);
}
}
public static class PeptideIterator implements Iterator<PepXmlPeptide>
{
private static Logger _log = Logger.getLogger(PepXmlLoader.class);
private SimpleXMLStreamReader _parser;
private PepXmlPeptide _peptide = null;
private MS2ModificationList _modifications;
private Map<Character, Integer> _unknownNTerminalModifications = new HashMap<Character, Integer>();
private Map<Character, Integer> _unknownNonNTerminalModifications = new HashMap<Character, Integer>();
protected PeptideIterator(SimpleXMLStreamReader parser, MS2ModificationList modifications)
{
_parser = parser;
_modifications = modifications;
}
protected void incrementUnknownModCount(Map<Character, Integer> mapToIncrement,
char charToIncrement)
{
Integer integerToIncrement = mapToIncrement.get(charToIncrement);
if (integerToIncrement == null)
integerToIncrement = 0;
mapToIncrement.put(charToIncrement, ++integerToIncrement);
}
public boolean hasNext()
{
try
{
_peptide = PepXmlPeptide.getNextPeptide(_parser, _modifications);
boolean result = (null != _peptide);
if (result)
{
//Sift through any unknown modifications and record them
//dhmay fixing bug 5904, 5/20/2008: adding null-check
if (_peptide._unknownModArray != null)
{
for (int i = 0; i < _peptide._unknownModArray.length; i++)
{
if (_peptide._unknownModArray[i])
{
if (i == 0)
incrementUnknownModCount(_unknownNTerminalModifications,
_peptide.getTrimmedPeptide().charAt(0));
else
{
incrementUnknownModCount(_unknownNonNTerminalModifications,
_peptide.getTrimmedPeptide().charAt(i));
//System.err.println("Unknown mod: " + _peptide.getPeptide() + ", " + i + ", " + _peptide.getTrimmedPeptide().charAt(i));
}
}
}
}
}
else
{
//End of the line, time to print out any unknown modifications
if (!_unknownNTerminalModifications.isEmpty())
{
_log.error("Error: Unknown N-Terminal Modifications. Counts per residue:");
for (char residue : _unknownNTerminalModifications.keySet())
{
_log.error("\t" + residue + ": " + _unknownNTerminalModifications.get(residue));
}
}
if (!_unknownNonNTerminalModifications.isEmpty())
{
_log.error("Error: Unknown non-N-Terminal Modifications:");
for (char residue : _unknownNonNTerminalModifications.keySet())
{
_log.error("\t" + residue + ": " + _unknownNonNTerminalModifications.get(residue));
}
}
}
return result;
}
catch (XMLStreamException e)
{
_log.error(e);
return false;
}
}
public PepXmlPeptide next()
{
return _peptide;
}
public void remove()
{
throw new UnsupportedOperationException();
}
}
public static class PepXmlPeptide
{
//keeps track of all unknown modifications we find, for later reporting
protected boolean[] _unknownModArray;
private SimpleXMLStreamReader _parser;
private int _scan, _endScan, _charge, _matchedIons, _totalIons, _proteinHits;
private Double _retentionTime = null;
private float _ionPercent, _deltaMass;
private double _calculatedNeutralMass;
//dhmay adding _numTolTerm 7/21/08. Default -1 value is a sentinel for "unset"
private int _numTolTerm = -1;
private String _peptide, _prevAA, _trimmedPeptide, _nextAA, _protein, _dtaFileName;
//dhmay adding _alternativeProteins 04/23/08
private List<String> _alternativeProteins;
//dhmay adding _alternativeNTTs 07/15/08
private List<Integer> _alternativeProteinNTTs;
private Integer hitRank = null;
private HashMap<String, String> _scores;
private MS2ModificationList _modifications;
private static final Pattern SCAN_REGEX = Pattern.compile("\\.??(\\d{1,6})\\.(\\d{1,6})\\.(\\d{1})\\.??[a-zA-z0-9_]*?$");
//This variable stays null unless there are actually modificationsIf there are,
//then all elements are null except the actual modifications. Index+1 = position of mod
private ModifiedAminoAcid[] _modifiedAminoAcids = null;
//These values stay 0 unless there is an n-terminal or c-terminal modification
private float _nTerminalModMass = 0f;
private float _cTerminalModMass = 0f;
private HashMap<String, PepXmlAnalysisResultHandler.PepXmlAnalysisResult> _analysisResultMap = null;
private static Logger _log = Logger.getLogger(PepXmlPeptide.class);
protected static PepXmlPeptide getNextPeptide(SimpleXMLStreamReader parser, MS2ModificationList modifications)
throws XMLStreamException
{
PepXmlPeptide peptide = new PepXmlPeptide(parser, modifications);
boolean success = peptide.load();
if (success)
return peptide;
else
return null;
}
private PepXmlPeptide(SimpleXMLStreamReader parser, MS2ModificationList modifications)
{
_parser = parser;
_modifications = modifications;
}
private static final int UNKNOWN = 0;
private static final int SEARCH_RESULT = 1;
private static final int SEARCH_HIT = 2;
private static final int ALTERNATIVE_PROTEIN = 3;
private static final int SEARCH_SCORE = 4;
private static final int ANALYSIS_RESULT = 5;
private static final int MSMS_RUN_SUMMARY = 6;
private static final int MODIFICATION_INFO = 7;
private static final int SPECTRUM_QUERY = 8;
private boolean endOfSpectrumQuery, endOfRun;
private static HashMap<String, Integer> elements;
static
{
elements = new HashMap<String, Integer>();
elements.put("search_result", SEARCH_RESULT);
elements.put("search_hit", SEARCH_HIT);
elements.put("alternative_protein", ALTERNATIVE_PROTEIN);
elements.put("search_score", SEARCH_SCORE);
elements.put("analysis_result", ANALYSIS_RESULT);
elements.put("msms_run_summary", MSMS_RUN_SUMMARY);
elements.put("modification_info", MODIFICATION_INFO);
elements.put("spectrum_query", SPECTRUM_QUERY);
}
protected boolean load() throws XMLStreamException
{
endOfSpectrumQuery = false;
endOfRun = false;
hitRank = null;
_scores = new HashMap<String, String>(10);
_alternativeProteins = new ArrayList<String>();
_alternativeProteinNTTs = new ArrayList<Integer>();
while (!endOfSpectrumQuery && !endOfRun)
{
if (_parser.isWhiteSpace())
{
_parser.next();
continue;
}
Integer element = elements.get(_parser.getLocalName());
int index = (null != element ? element.intValue() : UNKNOWN);
if (_parser.isStartElement())
processStartElement(index);
else
processEndElement(index);
if (endOfRun)
return false;
_parser.next();
}
fixUp();
return true;
}
protected void processStartElement(int index) throws XMLStreamException
{
switch (index)
{
case(SPECTRUM_QUERY):
_dtaFileName = _parser.getAttributeValue(null, "spectrum");
_scan = Integer.parseInt(_parser.getAttributeValue(null, "start_scan"));
String endScan = _parser.getAttributeValue(null, "end_scan");
_endScan = (null == endScan ? _scan : Integer.parseInt(endScan));
_charge = Integer.parseInt(_parser.getAttributeValue(null, "assumed_charge"));
// Retention time is optional, but if we find it, set it. If not, we'll retrieve it from the mzXML file and update
// the peptide record, but that's much more expensive.
String retentionTime = _parser.getAttributeValue(null, "retention_time_sec");
_retentionTime = (null != retentionTime ? Double.parseDouble(retentionTime) : null);
// Mascot exported pepXML can have start_scan="0" and end_scan="0"
if (0 == _scan)
{
Matcher m = SCAN_REGEX.matcher (_dtaFileName);
if (m.find())
{
// endScan=m.group(2), charge=m.group(3)
_scan = Integer.parseInt(m.group(1));
_endScan = Integer.parseInt(m.group(2));
}
}
break;
case(SEARCH_RESULT):
// Start over again within each spectrum_query block
hitRank = null;
break;
case(SEARCH_HIT):
Integer h = Integer.valueOf(_parser.getAttributeValue(null, "hit_rank"));
if (hitRank == null || h.compareTo(hitRank) <= 0)
{
hitRank = h;
_prevAA = _parser.getAttributeValue(null, "peptide_prev_aa");
_trimmedPeptide = _parser.getAttributeValue(null, "peptide");
_nextAA = _parser.getAttributeValue(null, "peptide_next_aa");
_proteinHits = Integer.parseInt(_parser.getAttributeValue(null, "num_tot_proteins"));
String numMatchedIons = _parser.getAttributeValue(null, "num_matched_ions");
String nttString = _parser.getAttributeValue(null, "num_tol_term");
if (nttString != null)
_numTolTerm = Integer.parseInt(nttString.trim());
//doing some null-checking here, just in case. Since we're generating
//some pepXml files ourselves, some of this stuff might be null
if (numMatchedIons != null)
_matchedIons = Integer.parseInt(numMatchedIons.trim());
else
_matchedIons = 0;
String totNumIons = _parser.getAttributeValue(null, "tot_num_ions");
if (totNumIons!= null)
_totalIons = Integer.parseInt(totNumIons.trim());
else
_totalIons = 0;
// Mascot exported pepXML may not report "tot_num_ions"
if (0 == _totalIons && _matchedIons > 0)
{
// let's attempt to guess the total ions as per sashimi
_totalIons = (_trimmedPeptide.length() - 1) * 2;
if (_charge>2)
{
// do it iteratively for charge 3, 4, 5, etc
for(int ionPerm=2; ionPerm<_charge; ionPerm++)
_totalIons *= 2;
}
}
_calculatedNeutralMass = Double.parseDouble(_parser.getAttributeValue(null, "calc_neutral_pep_mass"));
_unknownModArray = new boolean[_trimmedPeptide.length()];
// Handle illegal number in pepXML translator
String massDiff = _parser.getAttributeValue(null, "massdiff");
// For Sequest this needs to be a startsWith, since it outputs "+-0.00000"
if (massDiff == null || massDiff.startsWith("+-0.0"))
_deltaMass = 0.0f;
else
_deltaMass = Float.parseFloat(massDiff);
// Create protein lookup string that matches the way we import FASTA files (which matches what Comet does)
String proteinName = _parser.getAttributeValue(null, "protein");
if (proteinName != null)
{
Protein p = new Protein(proteinName, new byte[0]);
_protein = p.getLookup();
}
else
_protein = null;
}
else
{
_parser.skipToEnd("search_hit"); // TODO: Talk to Damon; remove "activeHit"?
}
break;
case(MODIFICATION_INFO):
_modifiedAminoAcids = new ModifiedAminoAcid[_trimmedPeptide.length()];
String ntermMassString = _parser.getAttributeValue(null, "mod_nterm_mass");
if (ntermMassString != null)
_nTerminalModMass = Float.parseFloat(ntermMassString);
String ctermMassString = _parser.getAttributeValue(null, "mod_cterm_mass");
if (ctermMassString != null)
_cTerminalModMass = Float.parseFloat(ctermMassString);
char[] modChars = new char[_trimmedPeptide.length()];
StringBuffer pep = new StringBuffer(_trimmedPeptide);
while (true)
{
_parser.next();
if (_parser.isWhiteSpace() || _parser.getEventType() == XMLStreamReader.COMMENT)
continue;
if ("mod_aminoacid_mass".equals(_parser.getLocalName()))
{
int position = Integer.parseInt(_parser.getAttributeValue(null, "position")) - 1;
char aa = _trimmedPeptide.charAt(position);
double modifiedMass = Rounder.round(Double.parseDouble(_parser.getAttributeValue(null, "mass")), 3);
MS2Modification mod = _modifications.get(String.valueOf(aa), modifiedMass);
// If null, it's either one of the mods that X! Tandem looks for on N-terminal amino acids Q, E, and C, and Tandem2XML isn't spitting out
// amino-acid tags OR it's a problem we don't understand
if (null == mod)
{
//System.err.println("No mod for " + String.valueOf(aa) + ", " + modifiedMass);
//record the unknown modification, but don't print out anything yet
_unknownModArray[position] = true;
_log.debug("Unknown modification at scan " + _scan + ": " + aa +
" " + modifiedMass);
}
else if (mod.getVariable())
modChars[position] = mod.getSymbol().charAt(0);
//paranoia
if (position <= _modifiedAminoAcids.length)
_modifiedAminoAcids[position] = new ModifiedAminoAcid(aa, modifiedMass);
_parser.next(); // end element
}
else
{
// Iterate in reverse order, so inserts don't invalidate future positions
for (int i = modChars.length - 1; i >= 0; i--)
if (0 != modChars[i])
pep.insert(i + 1, modChars[i]);
_peptide = pep.toString();
break;
}
}
break;
case(ALTERNATIVE_PROTEIN):
//dhmay adding handling for alternative proteins, 04/23/2008
String altProteinName = _parser.getAttributeValue(null, "protein");
if (altProteinName != null)
{
_alternativeProteins.add(altProteinName);
int numTolTerm = 2;
try
{
numTolTerm = Integer.parseInt(_parser.getAttributeValue(null, "num_tol_term"), 2);
}
catch (Exception e)
{
//this clutters up the logs, even in debug mode
// _log.debug("Missing alt protein NTT, defaulting to " + numTolTerm);
}
_alternativeProteinNTTs.add(numTolTerm);
}
break;
case(SEARCH_SCORE):
String name = _parser.getAttributeValue(null, "name");
String value = _parser.getAttributeValue(null, "value");
_scores.put(name, value);
break;
case(ANALYSIS_RESULT):
PepXmlAnalysisResultHandler.setAnalysisResult(_parser, this);
break;
case(UNKNOWN):
// _log.debug("unknown: " + parser.getLocalName());
break;
default:
// _log.debug("known, but no procedure: " + parser.getLocalName());
break;
}
}
protected void processEndElement(int index) throws XMLStreamException
{
switch (index)
{
case(SPECTRUM_QUERY):
endOfSpectrumQuery = true;
break;
case(MSMS_RUN_SUMMARY):
endOfRun = true;
break;
}
}
/**
* Called after peptide loading is complete
*/
private void fixUp()
{
if (null == _peptide)
_peptide = _trimmedPeptide;
_peptide = (_prevAA != null ? _prevAA + "." : "") +
_peptide + (_nextAA != null ? "." + _nextAA : "");
if (0 == _matchedIons || 0 == _totalIons)
_ionPercent = 0.0f;
else
_ionPercent = (float)(Rounder.round((float) _matchedIons / _totalIons, 2));
}
public int getCharge()
{
return _charge;
}
public Double getRetentionTime()
{
return _retentionTime;
}
public float getDeltaMass()
{
return _deltaMass;
}
public String getDtaFileName()
{
return _dtaFileName;
}
public float getIonPercent()
{
return _ionPercent;
}
public double getCalculatedNeutralMass()
{
return _calculatedNeutralMass;
}
public String getNextAA()
{
return _nextAA;
}
public String getPeptide()
{
return _peptide;
}
public String getPrevAA()
{
return _prevAA;
}
public String getProtein()
{
return _protein;
}
public int getProteinHits()
{
return _proteinHits;
}
public int getScan()
{
return _scan;
}
public int getEndScan()
{
return _endScan;
}
public Map<String, String> getScores()
{
return _scores;
}
public String getTrimmedPeptide()
{
return _trimmedPeptide;
}
public int getNumTolTerm()
{
return _numTolTerm;
}
protected void addAnalysisResult(String analysisType,
PepXmlAnalysisResultHandler.PepXmlAnalysisResult analysisResult)
{
if (_analysisResultMap == null)
_analysisResultMap = new HashMap<String, PepXmlAnalysisResultHandler.PepXmlAnalysisResult>();
_analysisResultMap.put(analysisType, analysisResult);
}
public PepXmlAnalysisResultHandler.PepXmlAnalysisResult getAnalysisResult(String analysisType)
{
if (_analysisResultMap == null)
return null;
return _analysisResultMap.get(analysisType);
}
public PeptideProphetHandler.PeptideProphetResult getPeptideProphetResult()
{
return (PeptideProphetHandler.PeptideProphetResult)
getAnalysisResult(PeptideProphetHandler.analysisType);
}
public XPressHandler.XPressResult getXPressResult()
{
return (XPressHandler.XPressResult)
getAnalysisResult(XPressHandler.analysisType);
}
public Q3Handler.Q3Result getQ3Result()
{
return (Q3Handler.Q3Result)
getAnalysisResult(Q3Handler.analysisType);
}
public ModifiedAminoAcid[] getModifiedAminoAcids()
{
return _modifiedAminoAcids;
}
public float getNTerminalModMass()
{
return _nTerminalModMass;
}
public float getCTerminalModMass()
{
return _cTerminalModMass;
}
/**
* Never null. Empty if nothing's there
* @return
*/
public List<String> getAlternativeProteins()
{
return _alternativeProteins;
}
/**
* Never null. Empty if nothing's there
* @return
*/
public List<Integer> getAlternativeProteinNTTs()
{
return _alternativeProteinNTTs;
}
}
/**
* TODO: Replace with StringUtils.join?
*/
private static String join(String delim, String[] strings)
{
if (strings == null) return null;
if (delim == null) delim = "";
StringBuffer sb = new StringBuffer();
for (String s : strings)
{
if (s != null)
{
sb.append(s);
sb.append(delim);
}
}
if (sb.length() <= delim.length())
return null;
return sb.substring(0, sb.length() - delim.length());
}
}