ions = ionsMap.get(subType);
+
+ if (ions == null) {
+
+ if (neutralLossesCombinations != null) {
+
+ ions = new ArrayList<>(neutralLossesCombinations.length);
+
+ } else {
+
+ ions = new ArrayList<>(1);
+
+ }
+
+ ionsMap.put(subType, ions);
+
+ }
+
+ if (neutralLossesCombinations != null) {
+
+ for (NeutralLossCombination losses : neutralLossesCombinations) {
+
+ ions.add(new PrecursorIon(forwardMass + h2o - losses.getMass(), losses.getNeutralLossCombination()));
+
+ }
+
+ // Add the precursor peak - oglycans
+ ions.add(new PrecursorIon(forwardMass + h2o - Playground.oglycan.getMass(), null));
+ // Add the precursor peak + 1
+ ions.add(new PrecursorIon(forwardMass + h2o + Atom.H.getMonoisotopicMass(), null));
+ // Add the precursor peak - oglycans
+ ions.add(new PrecursorIon(forwardMass + h2o + 2 * Atom.H.getMonoisotopicMass(), null));
+
+ } else {
+
+ ions.add(new PrecursorIon(forwardMass + ho, null));
+
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * This method returns the theoretic ions expected from a tag.
+ *
+ * /!\ this method will work only if the PTMs found in the tag are in the
+ * PTMFactory.
+ *
+ * @param tag the considered tag
+ * @param modificationParameters the modification parameters the
+ * modification parameters
+ * @param modificationsSequenceMatchingParameters the sequence matching
+ * parameters to use for modifications
+ * @return the expected fragment ions
+ */
+ public HashMap>> getFragmentIons(
+ Tag tag,
+ ModificationParameters modificationParameters,
+ SequenceMatchingParameters modificationsSequenceMatchingParameters
+ ) {
+
+ ModificationFactory modificationFactory = ModificationFactory.getInstance();
+
+ HashMap>> result = new HashMap<>();
+ HashSet possibleNeutralLosses = new HashSet<>(getDefaultNeutralLosses());
+
+ // We account for up to two neutral losses per ion maximum
+ NeutralLossCombination[] neutralLossesCombinations = getNeutralLossesCombinations(possibleNeutralLosses);
+
+ HashSet allModifications = new HashSet<>(2);
+
+ int ionNumberOffset = 1;
+ ArrayList massOffsets = new ArrayList<>();
+ massOffsets.add(0.0);
+
+ ArrayList tagContent = tag.getContent();
+
+ for (int tagIndex = 0; tagIndex < tagContent.size(); tagIndex++) {
+
+ TagComponent tagComponent = tagContent.get(tagIndex);
+
+ if (tagComponent instanceof AminoAcidSequence) {
+
+ AminoAcidSequence aminoAcidSequence = (AminoAcidSequence) tagComponent;
+ double sequenceMass = 0;
+
+ String[] variableModNames = aminoAcidSequence.getIndexedVariableModifications();
+ String[] fixedModNames = aminoAcidSequence.getFixedModifications(tagIndex == 0, tagIndex == tagContent.size() - 1, modificationParameters, modificationsSequenceMatchingParameters);
+
+ HashSet newModifications = new HashSet<>(0);
+ Modification[] variableModifications = new Modification[variableModNames.length];
+ Modification[] fixedModifications = new Modification[fixedModNames.length];
+
+ for (int i = 0; i < variableModifications.length; i++) {
+
+ String modName = variableModNames[i];
+
+ if (modName != null) {
+
+ if (!allModifications.contains(modName)) {
+ newModifications.add(modName);
+ allModifications.add(modName);
+ }
+
+ Modification modification = modificationFactory.getModification(modName);
+ variableModifications[i] = modification;
+
+ }
+
+ modName = fixedModNames[i];
+
+ if (modName != null) {
+
+ if (!allModifications.contains(modName)) {
+ newModifications.add(modName);
+ allModifications.add(modName);
+ }
+
+ Modification modification = modificationFactory.getModification(modName);
+ fixedModifications[i] = modification;
+
+ }
+ }
+
+ for (String modName : newModifications) {
+
+ Modification modification = ModificationFactory.getInstance().getModification(modName);
+
+ for (ReporterIon ptmReporterIon : modification.getReporterIons()) {
+ HashMap> ionsMap = result.get(Ion.IonType.REPORTER_ION.index);
+ if (ionsMap == null) {
+ ionsMap = new HashMap<>(1);
+ result.put(Ion.IonType.REPORTER_ION.index, ionsMap);
+ }
+ int subType = ptmReporterIon.getSubType();
+ ArrayList ions = ionsMap.get(subType);
+ if (ions == null) {
+ ions = new ArrayList<>(1);
+ ionsMap.put(subType, ions);
+ ions.add(ptmReporterIon);
+ }
+ }
+ for (NeutralLoss neutralLoss : modification.getNeutralLosses()) {
+ possibleNeutralLosses.add(neutralLoss.name);
+ }
+ }
+
+ for (int i = 0; i < aminoAcidSequence.length(); i++) {
+
+ AminoAcid aminoAcid = aminoAcidSequence.getAminoAcidAt(i);
+
+ // immonium ions
+ HashMap> ionsMap = result.get(Ion.IonType.IMMONIUM_ION.index);
+ if (ionsMap == null) {
+ ionsMap = new HashMap<>(1);
+ result.put(Ion.IonType.IMMONIUM_ION.index, ionsMap);
+ }
+ ImmoniumIon immoniumIon = ImmoniumIon.getImmoniumIon(aminoAcid.getSingleLetterCodeAsChar());
+ int subType = immoniumIon.getSubType();
+ ArrayList ions = ionsMap.get(subType);
+ if (ions == null) {
+ ions = new ArrayList<>(1);
+ ions.add(immoniumIon);
+ ionsMap.put(subType, ions);
+ }
+
+ // related ions
+ ionsMap = result.get(Ion.IonType.RELATED_ION.index);
+ if (ionsMap == null) {
+ ionsMap = new HashMap<>(1);
+ result.put(Ion.IonType.RELATED_ION.index, ionsMap);
+ }
+ ArrayList relatedIons = RelatedIon.getRelatedIons(aminoAcid);
+
+ if (relatedIons != null) {
+ for (RelatedIon tempRelated : relatedIons) {
+ subType = tempRelated.getSubType();
+
+ ions = ionsMap.get(subType);
+ if (ions == null) {
+ ions = new ArrayList<>(1);
+ }
+
+ ions.add(tempRelated);
+ ionsMap.put(subType, ions);
+ }
+ }
+
+ double mass = aminoAcid.getMonoisotopicMass();
+
+ Modification modification = variableModifications[i];
+
+ if (modification != null) {
+ mass += modification.getMass();
+ }
+
+ modification = fixedModifications[i];
+
+ if (modification != null) {
+ mass += modification.getMass();
+ }
+
+ sequenceMass += mass;
+
+ ionsMap = result.get(Ion.IonType.TAG_FRAGMENT_ION.index);
+ if (ionsMap == null) {
+ ionsMap = new HashMap<>();
+ result.put(Ion.IonType.TAG_FRAGMENT_ION.index, ionsMap);
+ }
+ for (double massOffset : massOffsets) {
+ int aa = ionNumberOffset + i;
+ int subaa = i + 1;
+ double forwardMass = massOffset + sequenceMass;
+
+ // add the a-ions
+ subType = TagFragmentIon.A_ION;
+ ions = ionsMap.get(subType);
+ if (ions == null) {
+ ions = new ArrayList<>();
+ ionsMap.put(subType, ions);
+ }
+ for (NeutralLossCombination losses : neutralLossesCombinations) {
+ ions.add(new TagFragmentIon(subType, aa, subaa, forwardMass - co - losses.getMass(), losses.getNeutralLossCombination(), massOffset));
+ }
+
+ // add the b-ions
+ subType = TagFragmentIon.B_ION;
+ ions = ionsMap.get(subType);
+ if (ions == null) {
+ ions = new ArrayList<>();
+ ionsMap.put(subType, ions);
+ }
+ for (NeutralLossCombination losses : neutralLossesCombinations) {
+ ions.add(new TagFragmentIon(subType, aa, subaa, forwardMass - losses.getMass(), losses.getNeutralLossCombination(), massOffset));
+ }
+
+ // add the c-ion
+ subType = TagFragmentIon.C_ION;
+ ions = ionsMap.get(subType);
+ if (ions == null) {
+ ions = new ArrayList<>();
+ ionsMap.put(subType, ions);
+ }
+ for (NeutralLossCombination losses : neutralLossesCombinations) {
+ ions.add(new TagFragmentIon(subType, aa, subaa, forwardMass + nh3 - losses.getMass(), losses.getNeutralLossCombination(), massOffset));
+ }
+ }
+ }
+ ArrayList newOffsetMasses = new ArrayList<>();
+ for (double offsetMass : massOffsets) {
+ double newMass = offsetMass + sequenceMass;
+ if (!newOffsetMasses.contains(newMass)) {
+ newOffsetMasses.add(newMass);
+ }
+ }
+ massOffsets = newOffsetMasses;
+ ionNumberOffset += aminoAcidSequence.length();
+ } else if (tagComponent instanceof MassGap) {
+ double gapMass = tagComponent.getMass();
+ int aa = ionNumberOffset;
+ int subaa = 0;
+
+ HashMap> ionsMap = result.get(Ion.IonType.TAG_FRAGMENT_ION.index);
+ if (ionsMap == null) {
+ ionsMap = new HashMap<>();
+ result.put(Ion.IonType.TAG_FRAGMENT_ION.index, ionsMap);
+ }
+
+ for (double massOffset : massOffsets) {
+ double forwardMass = massOffset + gapMass;
+
+ // add the a-ions
+ int subType = TagFragmentIon.A_ION;
+ ArrayList ions = ionsMap.get(subType);
+ if (ions == null) {
+ ions = new ArrayList<>();
+ ionsMap.put(subType, ions);
+ }
+ for (NeutralLossCombination losses : neutralLossesCombinations) {
+ ions.add(new TagFragmentIon(subType, aa, subaa, forwardMass - co - losses.getMass(), losses.getNeutralLossCombination(), massOffset));
+ }
+
+ // add the b-ions
+ subType = TagFragmentIon.B_ION;
+ ions = ionsMap.get(subType);
+ if (ions == null) {
+ ions = new ArrayList<>();
+ ionsMap.put(subType, ions);
+ }
+ for (NeutralLossCombination losses : neutralLossesCombinations) {
+ ions.add(new TagFragmentIon(subType, aa, subaa, forwardMass - losses.getMass(), losses.getNeutralLossCombination(), massOffset));
+ }
+
+ // add the c-ion
+ subType = TagFragmentIon.C_ION;
+ ions = ionsMap.get(subType);
+ if (ions == null) {
+ ions = new ArrayList<>();
+ ionsMap.put(subType, ions);
+ }
+ for (NeutralLossCombination losses : neutralLossesCombinations) {
+ ions.add(new TagFragmentIon(subType, aa, subaa, forwardMass + nh3 - losses.getMass(), losses.getNeutralLossCombination(), massOffset));
+ }
+
+ }
+ ArrayList newOffsetMasses = new ArrayList<>();
+ for (double offsetMass : massOffsets) {
+ newOffsetMasses.add(offsetMass + gapMass);
+ }
+ massOffsets = newOffsetMasses;
+ ionNumberOffset++;
+ } else {
+ throw new UnsupportedOperationException("Fragment ion not implemented for tag component " + tagComponent.getClass() + ".");
+ }
+ }
+
+ ArrayList reversedTag = new ArrayList<>(tag.getContent());
+ Collections.reverse(reversedTag);
+ ionNumberOffset = 0;
+ massOffsets.clear();
+ massOffsets.add(0.0);
+ allModifications.clear();
+ possibleNeutralLosses.clear();
+
+ for (int tagIndex = 0; tagIndex < tagContent.size(); tagIndex++) {
+
+ TagComponent tagComponent = tagContent.get(tagIndex);
+
+ if (tagComponent instanceof AminoAcidSequence) {
+
+ AminoAcidSequence aminoAcidSequence = (AminoAcidSequence) tagComponent;
+ double sequenceMass = 0;
+
+ String[] variableModNames = aminoAcidSequence.getIndexedVariableModifications();
+ String[] fixedModNames = aminoAcidSequence.getFixedModifications(tagIndex == 0, tagIndex == tagContent.size() - 1, modificationParameters, modificationsSequenceMatchingParameters);
+
+ HashSet newModifications = new HashSet<>(0);
+ Modification[] variableModifications = new Modification[variableModNames.length];
+ Modification[] fixedModifications = new Modification[fixedModNames.length];
+
+ for (int i = 0; i < variableModifications.length; i++) {
+
+ String modName = variableModNames[i];
+
+ if (modName != null) {
+
+ if (!allModifications.contains(modName)) {
+ newModifications.add(modName);
+ allModifications.add(modName);
+ }
+
+ Modification modification = modificationFactory.getModification(modName);
+ variableModifications[i] = modification;
+
+ }
+
+ modName = fixedModNames[i];
+
+ if (modName != null) {
+
+ if (!allModifications.contains(modName)) {
+ newModifications.add(modName);
+ allModifications.add(modName);
+ }
+
+ Modification modification = modificationFactory.getModification(modName);
+ fixedModifications[i] = modification;
+
+ }
+ }
+
+ for (String modName : newModifications) {
+
+ Modification modification = ModificationFactory.getInstance().getModification(modName);
+ for (NeutralLoss neutralLoss : modification.getNeutralLosses()) {
+ possibleNeutralLosses.add(neutralLoss.name);
+ }
+ }
+
+ for (int i = aminoAcidSequence.length() - 1; i >= 0; i--) {
+
+ AminoAcid aminoAcid = aminoAcidSequence.getAminoAcidAt(i);
+
+ // immonium ions
+ HashMap> ionsMap = result.get(Ion.IonType.IMMONIUM_ION.index);
+ if (ionsMap == null) {
+ ionsMap = new HashMap<>();
+ result.put(Ion.IonType.IMMONIUM_ION.index, ionsMap);
+ }
+ ImmoniumIon immoniumIon = ImmoniumIon.getImmoniumIon(aminoAcid.getSingleLetterCodeAsChar());
+ int subType = immoniumIon.getSubType();
+ ArrayList ions = ionsMap.get(subType);
+ if (ions == null) {
+ ions = new ArrayList<>();
+ ions.add(immoniumIon);
+ ionsMap.put(subType, ions);
+ }
+
+ // related ions
+ ionsMap = result.get(Ion.IonType.RELATED_ION.index);
+ if (ionsMap == null) {
+ ionsMap = new HashMap<>();
+ result.put(Ion.IonType.RELATED_ION.index, ionsMap);
+ }
+ ArrayList relatedIons = RelatedIon.getRelatedIons(aminoAcid);
+
+ if (relatedIons != null) {
+ for (RelatedIon tempRelated : relatedIons) {
+ subType = tempRelated.getSubType();
+
+ ions = ionsMap.get(subType);
+ if (ions == null) {
+ ions = new ArrayList<>(1);
+ }
+
+ ions.add(tempRelated);
+ ionsMap.put(subType, ions);
+ }
+ }
+
+ double mass = aminoAcid.getMonoisotopicMass();
+
+ Modification modification = variableModifications[i];
+
+ if (modification != null) {
+ mass += modification.getMass();
+ }
+
+ modification = fixedModifications[i];
+
+ if (modification != null) {
+ mass += modification.getMass();
+ }
+
+ sequenceMass += mass;
+
+ ionsMap = result.get(Ion.IonType.TAG_FRAGMENT_ION.index);
+ if (ionsMap == null) {
+ ionsMap = new HashMap<>();
+ result.put(Ion.IonType.TAG_FRAGMENT_ION.index, ionsMap);
+ }
+ for (double massOffset : massOffsets) {
+ int aa = ionNumberOffset + aminoAcidSequence.length() - i;
+ int subaa = aminoAcidSequence.length() - i;
+ double rewindMass = massOffset + sequenceMass;
+ double gap = 0;
+ if (massOffset != Atom.O.getMonoisotopicMass()) {
+ gap = massOffset;
+ }
+
+ // add the x-ions
+ subType = TagFragmentIon.X_ION;
+ ions = ionsMap.get(subType);
+ if (ions == null) {
+ ions = new ArrayList<>();
+ ionsMap.put(subType, ions);
+ }
+ for (NeutralLossCombination losses : neutralLossesCombinations) {
+ ions.add(new TagFragmentIon(subType, aa, subaa, rewindMass + co2 - losses.getMass(), losses.getNeutralLossCombination(), gap));
+ }
+
+ // add the y-ions
+ subType = TagFragmentIon.Y_ION;
+ ions = ionsMap.get(subType);
+ if (ions == null) {
+ ions = new ArrayList<>();
+ ionsMap.put(subType, ions);
+ }
+ for (NeutralLossCombination losses : neutralLossesCombinations) {
+ ions.add(new TagFragmentIon(subType, aa, subaa, rewindMass + h2o - losses.getMass(), losses.getNeutralLossCombination(), gap));
+ }
+
+ // add the z-ion
+ subType = TagFragmentIon.Z_ION;
+ ions = ionsMap.get(subType);
+ if (ions == null) {
+ ions = new ArrayList<>();
+ ionsMap.put(subType, ions);
+ }
+ for (NeutralLossCombination losses : neutralLossesCombinations) {
+ ions.add(new TagFragmentIon(subType, aa, subaa, rewindMass - nMinusO - losses.getMass(), losses.getNeutralLossCombination(), gap));
+ }
+ }
+ }
+ ArrayList newOffsetMasses = new ArrayList<>();
+ for (double offsetMass : massOffsets) {
+ double newMass = offsetMass + sequenceMass;
+ if (!newOffsetMasses.contains(newMass)) {
+ newOffsetMasses.add(newMass);
+ }
+ }
+ massOffsets = newOffsetMasses;
+ ionNumberOffset += aminoAcidSequence.length();
+ } else if (tagComponent instanceof MassGap) {
+ double gapMass = tagComponent.getMass();
+ int aa = ionNumberOffset;
+ int subaa = 0;
+
+ HashMap> ionsMap = result.get(Ion.IonType.TAG_FRAGMENT_ION.index);
+ if (ionsMap == null) {
+ ionsMap = new HashMap<>();
+ result.put(Ion.IonType.TAG_FRAGMENT_ION.index, ionsMap);
+ }
+ for (double massOffset : massOffsets) {
+ double gap = gapMass;
+ if (massOffset != Atom.O.getMonoisotopicMass()) {
+ gap += massOffset;
+ }
+ double rewindMass = massOffset + gapMass;
+
+ // add the x-ions
+ int subType = TagFragmentIon.X_ION;
+ ArrayList ions = ionsMap.get(subType);
+ if (ions == null) {
+ ions = new ArrayList<>();
+ ionsMap.put(subType, ions);
+ }
+ for (NeutralLossCombination losses : neutralLossesCombinations) {
+ ions.add(new TagFragmentIon(subType, aa, subaa, rewindMass + co2 - losses.getMass(), losses.getNeutralLossCombination(), gap));
+ }
+
+ // add the y-ions
+ subType = TagFragmentIon.Y_ION;
+ ions = ionsMap.get(subType);
+ if (ions == null) {
+ ions = new ArrayList<>();
+ ionsMap.put(subType, ions);
+ }
+ for (NeutralLossCombination losses : neutralLossesCombinations) {
+ ions.add(new TagFragmentIon(subType, aa, subaa, rewindMass + h2o - losses.getMass(), losses.getNeutralLossCombination(), gap));
+ }
+
+ // add the z-ion
+ subType = TagFragmentIon.Z_ION;
+ ions = ionsMap.get(subType);
+ if (ions == null) {
+ ions = new ArrayList<>();
+ ionsMap.put(subType, ions);
+ }
+ for (NeutralLossCombination losses : neutralLossesCombinations) {
+ ions.add(new TagFragmentIon(subType, aa, subaa, rewindMass - nMinusO - losses.getMass(), losses.getNeutralLossCombination(), gap));
+ }
+
+ }
+ ArrayList newOffsetMasses = new ArrayList<>();
+ for (double offsetMass : massOffsets) {
+ newOffsetMasses.add(offsetMass + gapMass);
+ }
+ massOffsets = newOffsetMasses;
+ ionNumberOffset++;
+ } else {
+ throw new UnsupportedOperationException("Fragment ion not implemented for tag component " + tagComponent.getClass() + ".");
+ }
+ }
+
+ // add the precursor ion
+ HashMap> ionsMap = result.get(Ion.IonType.PRECURSOR_ION.index);
+ if (ionsMap == null) {
+ ionsMap = new HashMap<>(1);
+ result.put(Ion.IonType.PRECURSOR_ION.index, ionsMap);
+ }
+ int subType = PrecursorIon.PRECURSOR;
+ ArrayList ions = ionsMap.get(subType);
+ if (ions == null) {
+ ions = new ArrayList<>(neutralLossesCombinations.length);
+ ionsMap.put(subType, ions);
+ }
+ for (NeutralLossCombination losses : neutralLossesCombinations) {
+ ions.add(new PrecursorIon(tag.getMass() - losses.getMass(), losses.getNeutralLossCombination()));
+ }
+
+ return result;
+ }
+
+ /**
+ * Returns the possible neutral losses combinations as array of arrays of
+ * neutral losses.
+ *
+ * @param possibleNeutralLosses the possible neutral losses to include
+ * @return the possible neutral losses combinations
+ */
+ public NeutralLossCombination[] getNeutralLossesCombinations(HashSet possibleNeutralLosses) {
+
+ long lossesKey = getNeutralLossesKey(possibleNeutralLosses);
+ NeutralLossCombination[] neutralLossesCombinations = neutralLossesCombinationsCache.get(lossesKey);
+
+ if (neutralLossesCombinations == null) {
+
+ ArrayList neutralLossesCombinationsLists = estimateNeutralLossesCombinations(possibleNeutralLosses);
+ neutralLossesCombinations = new NeutralLossCombination[neutralLossesCombinationsLists.size()];
+ for (int i = 0; i < neutralLossesCombinationsLists.size(); i++) {
+ NeutralLoss[] combination = neutralLossesCombinationsLists.get(i);
+ NeutralLossCombination combinationObject = new NeutralLossCombination(combination);
+ neutralLossesCombinations[i] = combinationObject;
+ }
+ neutralLossesCombinationsCache.put(lossesKey, neutralLossesCombinations);
+ }
+ return neutralLossesCombinations;
+ }
+
+ /**
+ * Convenience method returning the possible neutral losses combination as
+ * accounted by the factory, i.e., for now up to two neutral losses per
+ * peak.
+ *
+ * @param possibleNeutralLosses the possible neutral losses
+ * @return the possible combinations
+ */
+ private ArrayList estimateNeutralLossesCombinations(
+ HashSet possibleNeutralLosses
+ ) {
+
+ String[] lossesNames = possibleNeutralLosses.stream().sorted().toArray(String[]::new);
+
+ // We will account for up to two neutral losses per ion maximum
+ ArrayList neutralLossesCombinations = new ArrayList<>();
+ NeutralLoss[] tempList = new NeutralLoss[0];
+ neutralLossesCombinations.add(tempList);
+
+ for (int i = 0; i < lossesNames.length; i++) {
+
+ String name1 = lossesNames[i];
+ NeutralLoss neutralLoss1 = NeutralLoss.getNeutralLoss(name1);
+ tempList = new NeutralLoss[1];
+ tempList[0] = neutralLoss1;
+ neutralLossesCombinations.add(tempList);
+
+ for (int j = i + 1; j < lossesNames.length; j++) {
+
+ String name2 = lossesNames[j];
+ tempList = new NeutralLoss[2];
+ tempList[0] = neutralLoss1;
+ tempList[1] = NeutralLoss.getNeutralLoss(name2);
+ neutralLossesCombinations.add(tempList);
+
+ }
+ }
+
+ return neutralLossesCombinations;
+ }
+
+ /**
+ * Returns the neutral losses combination cache key corresponding to a set
+ * of neutral losses.
+ *
+ * @param possibleNeutralLosses the possible neutral losses
+ * @return the corresponding cache key
+ */
+ private long getNeutralLossesKey(
+ HashSet possibleNeutralLosses
+ ) {
+ return ExperimentObject.asLong(possibleNeutralLosses.stream()
+ .collect(Collectors.joining()));
+ }
+
+ /**
+ * Convenience summing the masses of various neutral losses.
+ *
+ * @param neutralLosses list of neutral losses
+ * @return the sum of the masses
+ */
+ public static double getLossesMass(
+ NeutralLoss[] neutralLosses
+ ) {
+
+ return Arrays.stream(neutralLosses)
+ .mapToDouble(NeutralLoss::getMass)
+ .sum();
+ }
+}
diff --git a/src/main/java/com/compomics/oglycans/PeptideGenerator.java b/src/main/java/com/compomics/oglycans/PeptideGenerator.java
new file mode 100644
index 0000000..5f8a8bf
--- /dev/null
+++ b/src/main/java/com/compomics/oglycans/PeptideGenerator.java
@@ -0,0 +1,143 @@
+package com.compomics.oglycans;
+
+import com.compomics.util.experiment.biology.enzymes.EnzymeFactory;
+import com.compomics.util.experiment.biology.modifications.Modification;
+import com.compomics.util.experiment.biology.proteins.Peptide;
+import com.compomics.util.experiment.biology.proteins.Protein;
+import com.compomics.util.experiment.identification.matches.ModificationMatch;
+import com.compomics.util.experiment.identification.protein_sequences.SingleProteinSequenceProvider;
+import com.compomics.util.experiment.identification.protein_sequences.digestion.ExtendedPeptide;
+import com.compomics.util.experiment.identification.protein_sequences.digestion.ProteinIteratorUtils;
+import com.compomics.util.experiment.identification.protein_sequences.digestion.SequenceIterator;
+import com.compomics.util.experiment.identification.protein_sequences.digestion.iterators.SpecificSingleEnzymeIterator;
+import com.compomics.util.experiment.io.biology.protein.SequenceProvider;
+import com.compomics.util.experiment.io.biology.protein.iterators.FastaIterator;
+import com.compomics.util.parameters.identification.advanced.SequenceMatchingParameters;
+import org.apache.log4j.Logger;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class PeptideGenerator {
+
+ private static final Logger LOGGER = Logger.getLogger(PeptideGenerator.class);
+
+ private EnzymeFactory enzymeFactory = EnzymeFactory.getInstance();
+ private ProteinIteratorUtils proteinIteratorUtils;
+ private List variableModifications;
+
+ public PeptideGenerator(List variableModifications) {
+ proteinIteratorUtils = new ProteinIteratorUtils(Playground.modificationParameters.getFixedModifications(), 1);
+ this.variableModifications = variableModifications;
+ }
+
+ /**
+ * Return a list of all peptide modification combinations from the given peptide FASTA file.
+ *
+ * @param fastaFile the FASTA file
+ * @return a list of {@link Peptide} objects
+ * @throws FileNotFoundException
+ */
+ public List readPeptideFasta(File fastaFile) throws FileNotFoundException {
+ List peptides = new ArrayList<>();
+
+ FastaIterator fastaIterator = new FastaIterator(fastaFile);
+ Protein protein;
+ while ((protein = fastaIterator.getNextProtein()) != null) {
+ List peptideModificationCombinations = getPeptideModificationCombinations(protein, protein.getSequence());
+ peptides.addAll(peptideModificationCombinations);
+ }
+
+ return peptides;
+ }
+
+ /**
+ * Returns a map of all peptide modification combinations for each protein from the given protein FASTA file.
+ *
+ * @param fastaFile the FASTA file
+ * @return a list of peptides for each protein
+ * @throws FileNotFoundException
+ * @throws InterruptedException
+ */
+ public Map> readProteinFasta(File fastaFile) throws FileNotFoundException, InterruptedException {
+ Map> proteinPeptides = new HashMap<>();
+
+ FastaIterator fastaIterator = new FastaIterator(fastaFile);
+ Protein protein;
+ while ((protein = fastaIterator.getNextProtein()) != null) {
+ List extendedPeptides = digestProtein(protein);
+ List peptides = new ArrayList<>();
+ for (ExtendedPeptide extendedPeptide : extendedPeptides) {
+ List peptideCombinations = getPeptideModificationCombinations(protein, extendedPeptide.peptide.getSequence());
+ peptides.addAll(peptideCombinations);
+ }
+ proteinPeptides.put(protein, peptides);
+ }
+
+ return proteinPeptides;
+ }
+
+ private List digestProtein(Protein protein) throws InterruptedException {
+ List extendedPeptides = new ArrayList<>();
+
+ SequenceIterator sequenceIterator = new SpecificSingleEnzymeIterator(proteinIteratorUtils, protein.getSequence(), enzymeFactory.getEnzyme("Trypsin"), 0, 800.0, 10000.0);
+ ExtendedPeptide extendedPeptide;
+ while ((extendedPeptide = sequenceIterator.getNextPeptide()) != null) {
+ extendedPeptides.add(extendedPeptide);
+ }
+
+ return extendedPeptides;
+ }
+
+ private List getPeptideModificationCombinations(Protein protein, String peptideSequence) {
+ List peptides = new ArrayList<>();
+
+ // I'm not sure if this is important
+ SequenceProvider sequenceProvider = new SingleProteinSequenceProvider(protein);
+
+ LOGGER.info("Calculating modification combinations for " + peptideSequence);
+
+ List> singleModificationCombinations = new ArrayList<>();
+ List uniqueModificationCombinations = new ArrayList<>();
+ for (Modification variableModification : variableModifications) {
+ List modificationSiteCombinations = CombinationUtils.getModificationSiteCombinations(variableModification, protein, peptideSequence);
+ singleModificationCombinations.add(modificationSiteCombinations);
+ modificationSiteCombinations.forEach(combination -> CombinationUtils.addArrayToList(uniqueModificationCombinations, combination));
+ }
+
+ // for each variable modification, combine the possible modifications with the other modification combinations
+ // and only keep the unique combinations
+ for (int i = 0; i < variableModifications.size(); i++) {
+ List newCombinations = CombinationUtils.combineModificationCombinations(uniqueModificationCombinations);
+ newCombinations.forEach(newCombination -> CombinationUtils.addArrayToList(uniqueModificationCombinations, newCombination));
+ }
+ for (String[] uniqueModificationCombination : uniqueModificationCombinations) {
+ Peptide peptide = new Peptide(peptideSequence);
+ for (int i = 0; i < peptide.getSequence().length(); i++) {
+ if (uniqueModificationCombination[i] != null) {
+ // check for pyroGlu
+ // TODO right now pyroGlu is on index 0 of the peptide because it's an N-terminal modification, check if this is OK
+ //if(ModificationFactory.getInstance().getModification(uniqueModificationCombination[i]).getModificationType() == ModificationType.modnaa_peptide){
+ if (uniqueModificationCombination[i].equals(Playground.pyroGly.getName())) {
+ peptide.addVariableModification(new ModificationMatch(uniqueModificationCombination[i], i));
+ } else {
+ peptide.addVariableModification(new ModificationMatch(uniqueModificationCombination[i], i + 1));
+ }
+ }
+ }
+ peptide.estimateTheoreticMass(Playground.modificationParameters, sequenceProvider, SequenceMatchingParameters.getDefaultSequenceMatching());
+ //System.out.print(peptide.getSequence() + " " + peptide.getMass() + " -> ");
+ //System.out.println(Arrays.toString(peptide.getIndexedVariableModifications()));
+ peptides.add(peptide);
+ }
+
+ LOGGER.info("Found " + peptides.size() + " modification combinations for " + peptideSequence);
+
+ return peptides;
+ }
+
+}
diff --git a/src/main/java/com/compomics/oglycans/PeptideIons.java b/src/main/java/com/compomics/oglycans/PeptideIons.java
new file mode 100644
index 0000000..9a0a580
--- /dev/null
+++ b/src/main/java/com/compomics/oglycans/PeptideIons.java
@@ -0,0 +1,241 @@
+package com.compomics.oglycans;
+
+import com.compomics.ms2io.model.Modification;
+import com.compomics.util.AA_Mass;
+import com.compomics.util.AtomMass;
+import com.compomics.util.experiment.biology.ions.Ion;
+import com.compomics.util.experiment.biology.ions.impl.PeptideFragmentIon;
+import com.compomics.util.experiment.biology.proteins.Peptide;
+import com.compomics.util.experiment.biology.proteins.Protein;
+import com.compomics.util.experiment.identification.protein_sequences.SingleProteinSequenceProvider;
+import com.compomics.util.experiment.io.biology.protein.SequenceProvider;
+import com.compomics.util.parameters.identification.advanced.SequenceMatchingParameters;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * @author Genet
+ */
+public class PeptideIons {
+
+ private String sequence = "";
+ private ArrayList ions;
+ private Map fragmentIons;
+ private Map modifications;
+ private HashMap>> utlitiesFragmentIons;
+
+ /**
+ * Constructor that takes a utilities {@link Peptide} object.
+ *
+ * @param peptide the peptide object
+ */
+ public PeptideIons(Peptide peptide, boolean decoy) {
+ modifications = new HashMap<>();
+ ions = new ArrayList<>();
+ this.sequence = peptide.getSequence();
+ SequenceProvider sequenceProvider = new SingleProteinSequenceProvider(new Protein("DUMMY_ACCESSION", peptide.getSequence()));
+ String[] variableModifications = peptide.getIndexedVariableModifications();
+ String[] fixedModifications = peptide.getFixedModifications(Playground.modificationParameters, sequenceProvider, SequenceMatchingParameters.getDefaultSequenceMatching());
+ int index;
+ this.utlitiesFragmentIons = IonFactory.getInstance().getFragmentIons(peptide, Playground.modificationParameters, sequenceProvider, SequenceMatchingParameters.getDefaultSequenceMatching());
+ //printUtilitiesFragmentIons();
+ for (int i = 0; i < variableModifications.length; i++) {
+ if (variableModifications[i] != null) {
+ com.compomics.util.experiment.biology.modifications.Modification utilitiesModification = Playground.utilitiesModifications.get(variableModifications[i]);
+
+ if (variableModifications[i].equals(Playground.pyroGly.getName())) {
+ index = i;
+ } else {
+ index = i - 1;
+ }
+
+ if (decoy) {
+ if (index != this.sequence.length() - 1) {
+ index = this.sequence.length() - 2 - index;
+ }
+ }
+
+ Modification modification = new Modification(index, peptide.getSequence().charAt(index), utilitiesModification.getMass(), utilitiesModification.getName());
+ modifications.put(index, modification);
+ }
+ }
+
+ for (int i = 0; i < fixedModifications.length; i++) {
+
+ if (fixedModifications[i] != null) {
+ com.compomics.util.experiment.biology.modifications.Modification utilitiesModification = Playground.utilitiesModifications.get(fixedModifications[i]);
+ index = i - 1;
+ Modification modification = new Modification(index, peptide.getSequence().charAt(index), utilitiesModification.getMass(), utilitiesModification.getName());
+ modifications.put(index, modification);
+ }
+ }
+ //fragment();
+ }
+
+ /**
+ * Generate the (fragment, precursor) ions for the given peptide.
+ *
+ * @param fragmentIonCharges the fragment ion charges to consider
+ * @return the list of ions
+ */
+ public List generateIons(List fragmentIonCharges) {
+ HashMap> peptideFragmentIons = utlitiesFragmentIons.get(Ion.IonType.PEPTIDE_FRAGMENT_ION.index);
+ for (Integer charge : fragmentIonCharges) {
+ // y ions
+ ArrayList ions = peptideFragmentIons.get(PeptideFragmentIon.Y_ION);
+ this.ions.addAll(ions.stream().filter(ion -> ion.getName().equals("y")).map(ion -> ion.getTheoreticMz(charge)).collect(Collectors.toList()));
+ // b ions
+ ions = peptideFragmentIons.get(PeptideFragmentIon.B_ION);
+ this.ions.addAll(ions.stream().filter(ion -> ion.getName().equals("b")).map(ion -> ion.getTheoreticMz(charge)).collect(Collectors.toList()));
+ // z ions
+ ions = peptideFragmentIons.get(PeptideFragmentIon.Z_ION);
+ this.ions.addAll(ions.stream().filter(ion -> ion.getName().equals("z")).map(ion -> ion.getTheoreticMz(charge)).collect(Collectors.toList()));
+ // c ions
+ ions = peptideFragmentIons.get(PeptideFragmentIon.C_ION);
+ this.ions.addAll(ions.stream().filter(ion -> ion.getName().equals("c")).map(ion -> ion.getTheoreticMz(charge)).collect(Collectors.toList()));
+
+ HashMap> precursorIons = utlitiesFragmentIons.get(Ion.IonType.PRECURSOR_ION.index);
+ this.ions.addAll(precursorIons.get(0).stream().map(ion -> ion.getTheoreticMz(charge)).collect(Collectors.toList()));
+ }
+
+ Collections.sort(ions);
+ return ions;
+ }
+
+ private void fragment() {
+ this.sequence = this.sequence.replaceAll("\\s+", "");
+ int len_seq = sequence.length();
+ int last_index = len_seq - 1;
+ for (int i = 0; i < len_seq; i++) {
+ String b_ion = sequence.substring(0, i + 1);
+ String y_ion = sequence.substring(last_index - i, len_seq);
+
+ int len_chars = i + 1;
+ double b_mass = 0;
+ double a_mass;
+ double c_mass;
+ double y_mass = 0;
+ double z_mass;
+ int bion_oglycans = 0;
+ int yion_oglycans = 0;
+
+ for (int j = 0; j < len_chars; j++) {
+
+ //String suffix = Integer.toString(len_chars); //number to append to the ion type
+
+ int y_index_track = last_index - i;
+ Modification mods;
+ b_mass += AA_Mass.getAA_mass(b_ion.charAt(j));
+ y_mass += AA_Mass.getAA_mass(y_ion.charAt(j));
+
+ if (!modifications.isEmpty()) {
+ if (modifications.containsKey(j)) {
+ //iterate over list of modification at this AA position
+
+ mods = modifications.get(j);
+ double mod = mods.getModificationMassShift();
+
+// for (int k = 0; k < mods.size(); k++) {
+// mod += Modification_Mass.getMassShift(mods.get(k));
+//
+// }
+ b_mass += mod;
+ if (Math.abs(mod - 503.3) < 0.001) {
+ bion_oglycans++;
+ }
+ }
+ if (modifications.containsKey(y_index_track + j)) {
+ //iterate over list of modification at this AA position
+ mods = modifications.get(y_index_track + j);
+ double mod = mods.getModificationMassShift();
+// for (int k = 0; k < mods.size(); k++) {
+// mod += Modification_Mass.getMassShift(mods.get(k));
+// }
+ y_mass += mod;
+
+ if (Math.abs(mod - 503.3) < 0.001) {
+ yion_oglycans++;
+ }
+ }
+
+ }
+
+ }
+
+ y_mass += AtomMass.getAtomMass("H1") * 2 + AtomMass.getAtomMass("O16");//water loss??
+ a_mass = b_mass - (AtomMass.getAtomMass("C12") + AtomMass.getAtomMass("O16"));
+ //fragments added for glycan fragments
+ c_mass = b_mass + (AtomMass.getAtomMass("N15") + AtomMass.getAtomMass("H1"));
+ z_mass = y_mass - (AtomMass.getAtomMass("N15") + AtomMass.getAtomMass("H1"));
+
+ //remove the oglycan mass shift from b and y ions, if it is already added(yion_oglycan!=0)
+ y_mass = y_mass - yion_oglycans * 503.3;
+ b_mass = b_mass - bion_oglycans * 503.3;
+
+
+ ions.add(y_mass);
+// frag_ion.add(y_mass / 2);
+//
+// frag_ion.add(b_mass);
+// frag_ion.add(b_mass / 2);
+// frag_ion.add(a_mass);
+// frag_ion.add(a_mass / 2);
+// frag_ion.add(c_mass);
+// frag_ion.add(c_mass / 2);
+// frag_ion.add(z_mass);
+// frag_ion.add(z_mass + 1);
+// frag_ion.add(z_mass + 1);
+// frag_ion.add(z_mass / 2);
+// frag_ion.add(z_mass / 3);
+// frag_ion.add(z_mass / 4);
+
+
+// frag_ion.add(Math.roung(y_mass*10000)/10000.0d);
+// frag_ion.add(Math.roung(y_mass*10000)/20000.0d);
+//
+// frag_ion.add(Math.roung(b_mass*10000)/10000.0d);
+// frag_ion.add(Math.roung(b_mass*10000)/20000.0d);
+// frag_ion.add(Math.roung(a_mass*10000)/10000.0d);
+// frag_ion.add(Math.roung(a_mass*10000)/20000.0d);
+// frag_ion.add(Math.roung(c_mass*10000)/10000.0d);
+// frag_ion.add(Math.roung(c_mass*10000)/20000.0d);
+// frag_ion.add(Math.roung(z_mass*10000)/10000.0d);
+// frag_ion.add(Math.roung(z_mass*10000)/20000.0d);
+// frag_ion.add(Math.roung(z_mass*10000)/30000.0d);
+// frag_ion.add(Math.roung(z_mass*10000)/40000.0d);
+ }
+ ions = (ArrayList) ions.stream().distinct().collect(Collectors.toList());
+ }
+
+ private void printUtilitiesFragmentIons() {
+ HashMap> peptideFragments = utlitiesFragmentIons.get(Ion.IonType.PEPTIDE_FRAGMENT_ION.index);
+ ArrayList ions = peptideFragments.get(PeptideFragmentIon.Y_ION);
+ HashMap> precursor = utlitiesFragmentIons.get(Ion.IonType.PRECURSOR_ION.index);
+ System.out.println("");
+ for (int i = 0; i < ions.size(); i++) {
+ if (ions.get(i).getName().equals("y")) {
+ System.out.println(ions.get(i).getName() + " " + ions.get(i).getTheoreticMass() + " " + ions.get(i).getTheoreticMz(1));
+ }
+ }
+
+ }
+
+ /**
+ * return fragment ion , mass map of sequence
+ *
+ * @return
+ */
+ public ArrayList getFragmentIon() {
+ return ions;
+ }
+
+ /**
+ * return modification
+ *
+ * @return
+ */
+ public Map getModification() {
+ return this.modifications;
+ }
+}
diff --git a/src/main/java/com/compomics/oglycans/Playground.java b/src/main/java/com/compomics/oglycans/Playground.java
new file mode 100644
index 0000000..5d9e04b
--- /dev/null
+++ b/src/main/java/com/compomics/oglycans/Playground.java
@@ -0,0 +1,98 @@
+package com.compomics.oglycans;
+
+import com.compomics.coss.model.ResourceUtils;
+import com.compomics.util.AtomMass;
+import com.compomics.util.experiment.biology.modifications.Modification;
+import com.compomics.util.experiment.biology.modifications.ModificationCategory;
+import com.compomics.util.experiment.biology.modifications.ModificationFactory;
+import com.compomics.util.experiment.biology.modifications.ModificationType;
+import com.compomics.util.experiment.biology.proteins.Peptide;
+import com.compomics.util.experiment.io.mass_spectrometry.mgf.MgfFileIterator;
+import com.compomics.util.experiment.mass_spectrometry.spectra.Spectrum;
+import com.compomics.util.gui.waiting.waitinghandlers.WaitingHandlerDummy;
+import com.compomics.util.parameters.identification.search.ModificationParameters;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class Playground {
+
+ private static ModificationFactory modificationFactory = ModificationFactory.getInstance();
+ public static final ModificationParameters modificationParameters = new ModificationParameters();
+ public static Modification oglycan;
+ public static final Modification oxidation = modificationFactory.getModification("Oxidation of M");
+ public static final Modification pyroGly = modificationFactory.getModification("Pyrolidone from E");
+ public static final Modification carbo = modificationFactory.getModification("Carbamidomethylation of C");
+ public static Map utilitiesModifications = new HashMap<>();
+ private static List variableModifications = new ArrayList<>();
+
+ static {
+ // add O-glycans mod with TMT label to ModificationFactory
+ ArrayList residues = new ArrayList<>();
+ residues.add("S");
+ residues.add("T");
+ oglycan = new Modification(ModificationType.modaa, "oglycans", 503.3, residues, ModificationCategory.Common);
+ modificationFactory.addUserModification(oglycan);
+
+ modificationParameters.addFixedModification(carbo);
+ modificationParameters.addVariableModification(oglycan);
+ modificationParameters.addVariableModification(oxidation);
+ modificationParameters.addVariableModification(pyroGly);
+
+ utilitiesModifications.put("oglycans", oglycan);
+ utilitiesModifications.put("Oxidation of M", oxidation);
+ utilitiesModifications.put("Pyrolidone from E", pyroGly);
+ utilitiesModifications.put("Carbamidomethylation of C", carbo);
+
+ variableModifications.add(oglycan);
+ variableModifications.add(oxidation);
+ variableModifications.add(pyroGly);
+ }
+
+ public Playground() {
+ }
+
+ public static void main(String[] args) {
+ List precursorCharges = new ArrayList<>();
+ precursorCharges.add(2);
+ precursorCharges.add(4);
+ precursorCharges.add(5);
+
+ try {
+ File output_file = new File("test.msp");
+ if (output_file.exists()) {
+ output_file.delete();
+ }
+
+ PeptideGenerator peptideGenerator = new PeptideGenerator(variableModifications);
+ List peptides = peptideGenerator.readPeptideFasta(ResourceUtils.getResourceByRelativePath("GlycopeptidePoolSmall.fasta").getFile());
+
+ // read the MGF file
+// MgfFileIterator mgfFileIterator = new MgfFileIterator(new File("/home/niels/Downloads/Niels_glycopeptide_pool/CMB-763_EThcD_export.mgf"), new WaitingHandlerDummy());
+// while (mgfFileIterator.next() != null) {
+// Spectrum spectrum = mgfFileIterator.getSpectrum();
+// for (Peptide peptide : peptides) {
+// for (Integer precursorCharge : precursorCharges) {
+// if (Math.abs((peptide.getMass() / precursorCharge) + precursorCharge * AtomMass.getAtomMass("H1") - spectrum.precursor.getMass(precursorCharge)) < 0.5) {
+// System.out.println("match");
+// }
+// }
+// }
+// }
+
+ SpectrumGenerator spectrumGenerator = new SpectrumGenerator();
+ spectrumGenerator.generateSpectra(peptides, output_file);
+
+ System.out.println("");
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/src/main/java/com/compomics/oglycans/SpectrumGenerator.java b/src/main/java/com/compomics/oglycans/SpectrumGenerator.java
new file mode 100644
index 0000000..02ba5c1
--- /dev/null
+++ b/src/main/java/com/compomics/oglycans/SpectrumGenerator.java
@@ -0,0 +1,136 @@
+package com.compomics.oglycans;
+
+import com.compomics.ms2io.model.*;
+import com.compomics.ms2io.controller.*;
+import com.compomics.util.AtomMass;
+import com.compomics.util.experiment.biology.proteins.Peptide;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Map;
+import java.util.List;
+
+import org.apache.commons.lang3.ArrayUtils;
+
+/**
+ * @author Genet
+ */
+public class SpectrumGenerator {
+
+ private List precursorCharges;
+ private List fragmentIonCharges;
+
+ public SpectrumGenerator() {
+ precursorCharges = new ArrayList<>();
+ precursorCharges.add(2);
+ precursorCharges.add(3);
+ precursorCharges.add(4);
+
+ fragmentIonCharges = new ArrayList<>();
+ fragmentIonCharges.add(1);
+// fragmentIonCharges.add(2);
+ }
+
+ public void generateSpectra(List peptides, File mgf_file) throws IOException {
+ SpectraWriter spw = new MspWriter(mgf_file);
+
+ ArrayList peaks = new ArrayList<>();
+ ArrayList decoyPeaks = new ArrayList<>();
+ for (Peptide peptide : peptides) {
+
+ // get fragment ions of the peptide
+ PeptideIons peptideIons = new PeptideIons(peptide, false);
+ List ions = peptideIons.generateIons(fragmentIonCharges);
+
+ // peak list
+ for (Double d : ions) {
+ Peak peak = new Peak(d, 600, "");
+ peaks.add(peak);
+ }
+
+ String mod_str = "";
+ for (Map.Entry entry : peptideIons.getModification().entrySet()) {
+ mod_str += entry.getValue().getModificationPosition() + "," + entry.getValue().getModifiedAA() + "," + entry.getValue().getModificationMassShift() + "\\";
+ }
+ if (mod_str != "") {
+ mod_str = mod_str.substring(0, mod_str.length() - 1);
+ } else {
+ mod_str = "0";
+ }
+
+ // make a spectrum for each precursor charge
+ for (Integer precursorCharge : precursorCharges) {
+ Spectrum spectrum = new Spectrum();
+ spectrum.setComment("Comment: " + "Parent=" + ((peptide.getMass() + precursorCharge * AtomMass.getAtomMass("H1")) / precursorCharge) + " " + "Mods=" + mod_str);
+ spectrum.setMW(0);
+ spectrum.setSequence(peptide.getSequence());
+ spectrum.setPCMass(peptide.getMass());
+ spectrum.setTitle(peptide.getSequence() + "/" + precursorCharge);
+ spectrum.setNumPeaks(ions.size());
+ spectrum.setPeakList(peaks);
+ spectrum.setCharge(precursorCharge.toString());
+ spw.write(spectrum);
+ }
+
+
+ // Generate decoy fragment ions from reverse sequence
+ // reverse sequence except the last aa
+ char[] tempSequence = peptide.getSequence().substring(0, peptide.getSequence().length() - 1).toCharArray();
+ ArrayUtils.reverse(tempSequence);
+ String reverseSequence = new String(tempSequence);
+ //add last aa to reversed sequence
+ reverseSequence += peptide.getSequence().charAt(peptide.getSequence().length() - 1);
+
+ //decoy_pep=peptide;
+ peptide.setSequence(reverseSequence);
+ //decoy_pep = new Peptide(rev_sequence);
+ // TODO ask Genet how to do this
+ PeptideIons decoyPeptideIons = new PeptideIons(peptide, true);
+
+ List decoyIons = decoyPeptideIons.generateIons(fragmentIonCharges);
+ Collections.sort(decoyIons);
+
+ //peak list of decoy
+ for (Double dd : decoyIons) {
+ Peak decoyPeak = new Peak(dd, 600, "");
+ decoyPeaks.add(decoyPeak);
+ }
+
+
+ Spectrum decoySpectrum = new Spectrum();
+ mod_str = "";
+ for (Map.Entry entry : decoyPeptideIons.getModification().entrySet()) {
+ mod_str += entry.getValue().getModificationPosition() + "," + entry.getValue().getModifiedAA() + "," + entry.getValue().getModificationMassShift() + "\\";
+
+ }
+ if (mod_str != "") {
+ mod_str = mod_str.substring(0, mod_str.length() - 1);
+ } else {
+ mod_str = "0";
+ }
+
+ for (Integer precursorCharge : precursorCharges) {
+ decoySpectrum.setComment("Comment: " + "Parent=" + ((peptide.getMass() + precursorCharge * AtomMass.getAtomMass("H1")) / precursorCharge) + " " + "Mods=" + mod_str + " _decoy");
+ decoySpectrum.setMW(0);
+ decoySpectrum.setSequence(reverseSequence);
+ decoySpectrum.setPCMass(peptide.getMass());
+ decoySpectrum.setTitle(reverseSequence + "/" + precursorCharge);
+ decoySpectrum.setNumPeaks(decoyIons.size());
+ decoySpectrum.setPeakList(decoyPeaks);
+ decoySpectrum.setCharge(precursorCharge.toString());
+ spw.write(decoySpectrum);
+ }
+
+ peaks.clear();
+ decoyPeaks.clear();
+ ions.clear();
+ decoyIons.clear();
+
+ }
+ spw.closeWriter();
+
+ }
+
+}
diff --git a/src/main/java/com/compomics/util/FragmentIon.java b/src/main/java/com/compomics/util/FragmentIon.java
index 63731f2..5f94857 100644
--- a/src/main/java/com/compomics/util/FragmentIon.java
+++ b/src/main/java/com/compomics/util/FragmentIon.java
@@ -48,7 +48,6 @@ private void fragment() {
int y_index_track =last_index - i;
Modification mods;
for (int j = 0; j < len_chars; j++) {
-
b_mass += AA_Mass.getAA_mass(b_ion.charAt(j));
y_mass += AA_Mass.getAA_mass(y_ion.charAt(j));
diff --git a/src/main/java/com/compomics/util/Modification_Mass.java b/src/main/java/com/compomics/util/Modification_Mass.java
index f7c2ed3..375fbc9 100644
--- a/src/main/java/com/compomics/util/Modification_Mass.java
+++ b/src/main/java/com/compomics/util/Modification_Mass.java
@@ -11,6 +11,7 @@
*/
public final class Modification_Mass {
+ private static final double OGlycan = 503.3;
private static final double CAM = 57.021464;
private static final double Oxidation = 15.994915;
private static final double Pyro_glu_E = -18.010565; // Pyro-glu from E (Glu -> pyro-Glu) //modified
@@ -59,6 +60,9 @@ public static double getMassShift(String mod_name){
double mass=0.0;
switch(mod_name){
+
+ case "OGlycan": mass = 503.3;
+ break;
case "CAM": mass = 57.021464;
break;
case "Oxidation": mass = 15.994915;
diff --git a/src/main/resources/GlycopeptidePool.fasta b/src/main/resources/GlycopeptidePool.fasta
new file mode 100644
index 0000000..f333d81
--- /dev/null
+++ b/src/main/resources/GlycopeptidePool.fasta
@@ -0,0 +1,299 @@
+>1
+AMSEVTSLHEDDWR
+
+>2
+APIISGVTK
+
+>3
+APVGSVVSVPSQSSASSDK
+
+>4
+AQPSASLGVGYR
+
+>5
+ASPPLFQSR
+
+>6
+ASTPGAAAQIQEVK
+
+>7
+ATAVVDGAFK
+
+>8
+AVAITQSPSSVR
+
+>9
+DSLGVSFPEELACK
+
+>10
+DVFISAAER
+
+>11
+EEKPAVTAAPK
+
+>12
+EGFSIPVSADGFK
+
+>13
+ELANFDPSRPGPPSGR
+
+>14
+ESISVSSEQLAQFR
+
+>15
+EVVKPVPITSPAVSK
+
+>16
+FELLPTPPLSPSRR
+
+>17
+FGVEAFSDCLR
+
+>18
+FIHQQPQSSSPVYGSSAK
+
+>19
+FSPPSSSLQPGK
+
+>20
+FSYTSQHSDYGQR
+
+>21
+FSYTSQHSDYGQR
+
+>22
+GSHGQTPSPGALPLGR
+
+>23
+HVSPVTPPR
+
+>24
+IEDEQALGSQLQK
+
+>25
+IGSLDNITHVPGGGNK
+
+>26
+IPAASAAAMNLASAR
+
+>27
+IQTVPASHLQQGTASGSSK
+
+>28
+ISEILLDHGAPIQAK
+
+>29
+ISEILLDHGAPIQAK
+
+>30
+KSQAGASELGPFSDPR
+
+>31
+KVTLSVLSR
+
+>32
+LGHYATQLQK
+
+>33
+LGSASSSHGSIQESHK
+
+>34
+LSEHATAPTR
+
+>35
+LSESHPDATEDLQR
+
+>36
+LSQEDPDYGIR
+
+>37
+LSTPPPLAEEEGLASR
+
+>38
+LVSESSDVLPK
+
+>39
+MFLSFPTTK
+
+>40
+MSQQYGDVLQIR
+
+>41
+MTLSVLSR
+
+>42
+NLVTGDHIPTPQDLPQR
+
+>43
+QGNAVTLGDYYQGR
+
+>44
+RFSPPSSSLQPGK
+
+>45
+SGYSSPGSPGTPGSR
+
+>46
+SISQSISGQK
+
+>47
+SLYASSPGGVYATR
+
+>48
+SSDLTDRVK
+
+>49
+SSSAGGQGSYVPLLR
+
+>50
+SVGGSGGGSFGDNLVTR
+
+>51
+SYISSQTNDTHK
+
+>52
+TLTPASSPVSSPSKHGDR
+
+>53
+TQSFSLQER
+
+>54
+TSAVSSQANSQPPVQVSVK
+
+>55
+TSSEASVSSSVAK
+
+>56
+TTSYPTPRPYPKPAPSSGK
+
+>57
+VAVLGASGGIGQPLSLLLK
+
+>58
+VILENIASHEPR
+
+>59
+VLDASWYSPGTR
+
+>60
+VLPSITTEILK
+
+>61
+VLSIGDGIAR
+
+>62
+VMVAPISGSVTTGTK
+
+>63
+VPQAQPTKPALK
+
+>64
+VTGGIFSVTK
+
+>65
+YIDNQVVSTKGER
+
+>66
+TTLTSDESVKDHTTAGR
+
+>67
+LSFGLEDEPLETATK
+
+>68
+GQDSTIAASEQQVAAR
+
+>69
+LVTLEEFLASTQR
+
+>70
+DYSQPTAAATVQDIK
+
+>71
+DFSLTSSSQTPGATK
+
+>72
+ASTYGSTQQLAEMWLEK
+
+>73
+ITATTTQVTSTTTQDTTPFK
+
+>74
+TEITSTAETFGFEAK
+
+>75
+VEELEGEITTLNHK
+
+>76
+KITESVAETAQTIK
+
+>77
+LGNTISSLFGGGTTPDAK
+
+>78
+TAGSSGVTAGRPRPTAR
+
+>79
+VGADGTVFATR
+
+>80
+TATLATLATR
+
+>81
+ITESVAETAQTIK
+
+>82
+ITESVAETAQTIKK
+
+>83
+RLDINTNTYTSQDLK
+
+>84
+ETTPSSLAVTQTMATK
+
+>85
+SALAAAQTQVAEYK
+
+>86
+STLEEPNLQPLQR
+
+>87
+THLGEALAPLSK
+
+>88
+SLIGKVDGTSHVTGK
+
+>89
+SFSASGAQIVSR
+
+>90
+TELLPGDRDNLAIQTR
+
+>91
+LPTTAASTPDAVDK
+
+>92
+DHSKPISNPSDNK
+
+>93
+TPLTHALPGLSEQEGQK
+
+>94
+SAGSVESPSVSSTHR
+
+>95
+ISPVEESEDVSNK
+
+>96
+EPFSGDHSADGFEVTSR
+
+>97
+QQETAAAETETR
+
+>98
+SQLANTEPTK
+
+>99
+HEVTGWVLVSPLSK
+
+>100
+VDGDTQTTVEK
\ No newline at end of file
diff --git a/src/main/resources/GlycopeptidePoolSmall.fasta b/src/main/resources/GlycopeptidePoolSmall.fasta
new file mode 100644
index 0000000..ad764ea
--- /dev/null
+++ b/src/main/resources/GlycopeptidePoolSmall.fasta
@@ -0,0 +1,2 @@
+>1
+AMSEVTSLHEDDWR
diff --git a/src/main/resources/PeptidePoolContatenated.fasta b/src/main/resources/PeptidePoolContatenated.fasta
new file mode 100644
index 0000000..8a94510
--- /dev/null
+++ b/src/main/resources/PeptidePoolContatenated.fasta
@@ -0,0 +1,2 @@
+>tr|W00001|W00001_HUMAN Concatenated Peptide Pool OS=Homo sapiens OX=9606 GN=IFNGR2 PE=1 SV=1
+AMSEVTSLHEDDWRAPIISGVTKAPVGSVVSVPSQSSASSDKAQPSASLGVGYRASPPLFQSRASTPGAAAQIQEVKATAVVDGAFKAVAITQSPSSVRDSLGVSFPEELACKDVFISAAEREEKPAVTAAPKEGFSIPVSADGFKELANFDPSRPGPPSGRESISVSSEQLAQFREVVKPVPITSPAVSKFELLPTPPLSPSRRFGVEAFSDCLRFIHQQPQSSSPVYGSSAKFSPPSSSLQPGKFSYTSQHSDYGQRGSAPPGPVPEGSIRGSHGQTPSPGALPLGRHVSPVTPPRIEDEQALGSQLQKIGSLDNITHVPGGGNKIPAASAAAMNLASARIQTVPASHLQQGTASGSSKISEILLDHGAPIQAKIVNVSLADLRKSQAGASELGPFSDPRKVTLSVLSRLGHYATQLQKLGSASSSHGSIQESHKLSEHATAPTRLSESHPDATEDLQRLSQEDPDYGIRLSTPPPLAEEEGLASRLVSESSDVLPKMFLSFPTTKMSQQYGDVLQIRMTLSVLSRNLVTGDHIPTPQDLPQRQGNAVTLGDYYQGRRFSPPSSSLQPGKSGYSSPGSPGTPGSRSISQSISGQKSLYASSPGGVYATRSSDLTDRVKSSSAGGQGSYVPLLRSVGGSGGGSFGDNLVTRSYISSQTNDTHKTLTPASSPVSSPSKHGDRTQSFSLQERTSAVSSQANSQPPVQVSVKTSSEASVSSSVAKTTSYPTPRPYPKPAPSSGKVAVLGASGGIGQPLSLLLKVILENIASHEPRVLDASWYSPGTRVLPSITTEILKVLSIGDGIARVMVAPISGSVTTGTKVPQAQPTKPALKVTGGIFSVTKYIDNQVVSTKGERTTLTSDESVKDHTTAGRLSFGLEDEPLETATKGQDSTIAASEQQVAARLVTLEEFLASTQRDYSQPTAAATVQDIKDFSLTSSSQTPGATKASTYGSTQQLAEMWLEKITATTTQVTSTTTQDTTPFKTEITSTAETFGFEAKVEELEGEITTLNHKKITESVAETAQTIKLGNTISSLFGGGTTPDAKTAGSSGVTAGRPRPTARVGADGTVFATRTATLATLATRITESVAETAQTIKITESVAETAQTIKKRLDINTNTYTSQDLKETTPSSLAVTQTMATKSALAAAQTQVAEYKSTLEEPNLQPLQRTHLGEALAPLSKSLIGKVDGTSHVTGKSFSASGAQIVSRTELLPGDRDNLAIQTRLPTTAASTPDAVDKDHSKPISNPSDNKTPLTHALPGLSEQEGQKSAGSVESPSVSSTHRISPVEESEDVSNKEPFSGDHSADGFEVTSRQQETAAAETETRSQLANTEPTKHEVTGWVLVSPLSKVDGDTQTTVEK
diff --git a/src/main/resources/config.properties b/src/main/resources/config.properties
index dfce80c..090ac33 100644
--- a/src/main/resources/config.properties
+++ b/src/main/resources/config.properties
@@ -5,9 +5,9 @@ coss.version = 1.0
##############################
-target.spectra.path =D:/percolator_coss_test/Adult_Colon_bRP_Elite_50_f24.mgf
+target.spectra.path =/home/niels/Downloads/Niels_glycopeptide_pool/Unfiltered_EThcD_111.mgf
#C:/Users/Genet/OneDrive - UGent/6_TestFilesNAnalysis/SpecA.msp
-spectra.library.path = D:/human_hcd_fromC/lib/PRIDE/Human_TDrandomIntMzShift.msp
+spectra.library.path = /home/niels/Documents/Development/Projects/COSS/test.msp
# C:/Users/Genet/OneDrive - UGent/6_TestFilesNAnalysis/SpecB.msp
#C:/Users/Genet/OneDrive - UGent/6_TestFilesNAnalysis/SpecA.msb
#C:/Users/Genet/OneDrive - UGent/6_TestFilesNAnalysis/SpecB.msb
@@ -17,9 +17,9 @@ result.path = D:/COSS_Result
## MS1 and MS2error value in ppm
## If this is set to 0, no precursor tolerance is selected (in Da)
-precursor.tolerance = 10
+precursor.tolerance = 0.5
# The fragment tolerance unit is in ppm.
-fragment.tolerance = 0.05
+fragment.tolerance = 10
##############################
## Preprocessing parameters ##
diff --git a/src/test/java/com/compomics/coss/oglycans/CombinationUtilsTest.java b/src/test/java/com/compomics/coss/oglycans/CombinationUtilsTest.java
new file mode 100644
index 0000000..aa30069
--- /dev/null
+++ b/src/test/java/com/compomics/coss/oglycans/CombinationUtilsTest.java
@@ -0,0 +1,87 @@
+package com.compomics.coss.oglycans;
+
+import com.compomics.oglycans.CombinationUtils;
+import com.compomics.util.experiment.biology.modifications.Modification;
+import com.compomics.util.experiment.biology.modifications.ModificationCategory;
+import com.compomics.util.experiment.biology.modifications.ModificationFactory;
+import com.compomics.util.experiment.biology.modifications.ModificationType;
+import com.compomics.util.experiment.biology.proteins.Protein;
+import org.junit.AfterClass;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class CombinationUtilsTest {
+
+ private static ModificationFactory modificationFactory = ModificationFactory.getInstance();
+
+ @BeforeClass
+ public static void setUpClass() throws Exception {
+ // add O-glycans mod with TMT label to ModificationFactory
+ ArrayList residues = new ArrayList<>();
+ residues.add("S");
+ residues.add("T");
+ Modification oglycan = new Modification(ModificationType.modaa, "oglycans", 503.3, residues, ModificationCategory.Common);
+ modificationFactory.addUserModification(oglycan);
+ }
+
+ @Test
+ public void testCombineModificationCombinations() {
+ List modificationCombinations = new ArrayList<>();
+ modificationCombinations.add(new String[]{"mod1", null, null});
+ modificationCombinations.add(new String[]{null, "mod2", null});
+ modificationCombinations.add(new String[]{null, null, "mod3"});
+
+ List combinations = CombinationUtils.combineModificationCombinations(modificationCombinations);
+ Assert.assertEquals(3, combinations.size());
+ Assert.assertTrue(combinations.stream().anyMatch(a -> Arrays.equals(a, new String[]{"mod1", "mod2", null})));
+ Assert.assertTrue(combinations.stream().anyMatch(a -> Arrays.equals(a, new String[]{"mod1", null, "mod3"})));
+ Assert.assertTrue(combinations.stream().anyMatch(a -> Arrays.equals(a, new String[]{null, "mod2", "mod3"})));
+ }
+
+ @Test
+ public void testGetCombinationsForModificationOccurrence() {
+ List possibleModificationSiteCombinations = CombinationUtils.getCombinationsForModificationOccurrence(8, "mod", new int[]{2, 4, 6}, 0);
+ Assert.assertEquals(1, possibleModificationSiteCombinations.size());
+ Assert.assertTrue(possibleModificationSiteCombinations.stream().anyMatch(a -> Arrays.equals(a, new String[]{null, null, null, null, null, null, null, null})));
+
+ possibleModificationSiteCombinations = CombinationUtils.getCombinationsForModificationOccurrence(8, "mod", new int[]{2, 4, 6}, 1);
+
+ Assert.assertEquals(3, possibleModificationSiteCombinations.size());
+ Assert.assertTrue(possibleModificationSiteCombinations.stream().anyMatch(a -> Arrays.equals(a, new String[]{null, "mod", null, null, null, null, null, null})));
+ Assert.assertTrue(possibleModificationSiteCombinations.stream().anyMatch(a -> Arrays.equals(a, new String[]{null, null, null, null, null, "mod", null, null})));
+ Assert.assertTrue(possibleModificationSiteCombinations.stream().anyMatch(a -> Arrays.equals(a, new String[]{null, null, null, "mod", null, null, null, null})));
+
+ possibleModificationSiteCombinations = CombinationUtils.getCombinationsForModificationOccurrence(8, "mod", new int[]{2, 4, 6}, 2);
+
+ Assert.assertEquals(3, possibleModificationSiteCombinations.size());
+ Assert.assertTrue(possibleModificationSiteCombinations.stream().anyMatch(a -> Arrays.equals(a, new String[]{null, "mod", null, "mod", null, null, null, null})));
+ Assert.assertTrue(possibleModificationSiteCombinations.stream().anyMatch(a -> Arrays.equals(a, new String[]{null, "mod", null, null, null, "mod", null, null})));
+ Assert.assertTrue(possibleModificationSiteCombinations.stream().anyMatch(a -> Arrays.equals(a, new String[]{null, null, null, "mod", null, "mod", null, null})));
+
+ possibleModificationSiteCombinations = CombinationUtils.getCombinationsForModificationOccurrence(8, "mod", new int[]{2, 4, 6}, 3);
+
+ Assert.assertEquals(1, possibleModificationSiteCombinations.size());
+ Assert.assertTrue(possibleModificationSiteCombinations.stream().anyMatch(a -> Arrays.equals(a, new String[]{null, "mod", null, "mod", null, "mod", null, null})));
+ }
+
+ @Test
+ public void testGetModificationSiteCombinations() {
+ Protein protein = new Protein("TEST", "TEST");
+ List combinations = CombinationUtils.getModificationSiteCombinations(modificationFactory.getModification("oglycans"), protein, "TEST");
+ Assert.assertEquals(8, combinations.size());
+ Assert.assertTrue(combinations.stream().anyMatch(a -> Arrays.equals(a, new String[]{null, null, null, null})));
+ Assert.assertTrue(combinations.stream().anyMatch(a -> Arrays.equals(a, new String[]{"oglycans", null, null, null})));
+ Assert.assertTrue(combinations.stream().anyMatch(a -> Arrays.equals(a, new String[]{null, null, "oglycans", null})));
+ Assert.assertTrue(combinations.stream().anyMatch(a -> Arrays.equals(a, new String[]{null, null, null, "oglycans"})));
+ Assert.assertTrue(combinations.stream().anyMatch(a -> Arrays.equals(a, new String[]{"oglycans", null, "oglycans", null})));
+ Assert.assertTrue(combinations.stream().anyMatch(a -> Arrays.equals(a, new String[]{"oglycans", null, null, "oglycans"})));
+ Assert.assertTrue(combinations.stream().anyMatch(a -> Arrays.equals(a, new String[]{null, null, "oglycans", "oglycans"})));
+ Assert.assertTrue(combinations.stream().anyMatch(a -> Arrays.equals(a, new String[]{"oglycans", null, "oglycans", "oglycans"})));
+ }
+
+}
diff --git a/src/test/java/com/compomics/coss/oglycans/PeptideGeneratorTest.java b/src/test/java/com/compomics/coss/oglycans/PeptideGeneratorTest.java
new file mode 100644
index 0000000..a14b4f1
--- /dev/null
+++ b/src/test/java/com/compomics/coss/oglycans/PeptideGeneratorTest.java
@@ -0,0 +1,70 @@
+package com.compomics.coss.oglycans;
+
+import com.compomics.oglycans.PeptideGenerator;
+import com.compomics.util.experiment.biology.modifications.Modification;
+import com.compomics.util.experiment.biology.modifications.ModificationCategory;
+import com.compomics.util.experiment.biology.modifications.ModificationFactory;
+import com.compomics.util.experiment.biology.modifications.ModificationType;
+import com.compomics.util.experiment.biology.proteins.Peptide;
+import com.compomics.util.experiment.biology.proteins.Protein;
+import com.compomics.util.experiment.identification.protein_sequences.SingleProteinSequenceProvider;
+import com.compomics.util.experiment.io.biology.protein.SequenceProvider;
+import com.compomics.util.parameters.identification.advanced.SequenceMatchingParameters;
+import com.compomics.util.parameters.identification.search.ModificationParameters;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.util.ArrayList;
+import java.util.List;
+
+public class PeptideGeneratorTest {
+
+ private PeptideGenerator peptideGenerator;
+
+ @Before
+ public void initialize() {
+ List variableModifications = new ArrayList<>();
+
+ Modification oxidation = ModificationFactory.getInstance().getModification("Oxidation of M");
+ Modification pyroGly = ModificationFactory.getInstance().getModification("Pyrolidone from E");
+ // add O-glycans mod with TMT label to ModificationFactory
+ ArrayList residues = new ArrayList<>();
+ residues.add("S");
+ residues.add("T");
+ Modification oglycan = new Modification(ModificationType.modaa, "oglycans", 503.3, residues, ModificationCategory.Common);
+ ModificationFactory.getInstance().addUserModification(oglycan);
+
+ variableModifications.add(oglycan);
+ variableModifications.add(oxidation);
+ variableModifications.add(pyroGly);
+
+ peptideGenerator = new PeptideGenerator(variableModifications);
+ }
+
+ @Test
+ public void testReadPeptideFasta1() throws FileNotFoundException {
+ List peptides = peptideGenerator.readPeptideFasta(new File("src/test/resources/oglycans_test_1.fasta"));
+
+ Assert.assertEquals(8, peptides.size());
+
+ // check the if a fixed modification is taken into account as well
+ ModificationParameters modificationParameters = new ModificationParameters();
+ Modification carbo = ModificationFactory.getInstance().getModification("Carbamidomethylation of C");
+ modificationParameters.addFixedModification(carbo);
+ Peptide peptide = peptides.get(0);
+ SequenceProvider sequenceProvider = new SingleProteinSequenceProvider(new Protein("TESTACCESSION", peptide.getSequence()));
+ String[] fixedModifications = peptide.getFixedModifications(modificationParameters, sequenceProvider, SequenceMatchingParameters.getDefaultSequenceMatching());
+ Assert.assertEquals("Carbamidomethylation of C", fixedModifications[4]);
+ }
+
+ @Test
+ public void testReadPeptideFasta2() throws FileNotFoundException {
+ List peptides = peptideGenerator.readPeptideFasta(new File("src/test/resources/oglycans_test_2.fasta"));
+
+ Assert.assertEquals(8, peptides.size());
+ }
+
+}
diff --git a/src/test/resources/oglycans_test_1.fasta b/src/test/resources/oglycans_test_1.fasta
new file mode 100644
index 0000000..006ce27
--- /dev/null
+++ b/src/test/resources/oglycans_test_1.fasta
@@ -0,0 +1,2 @@
+>0
+ESMC
\ No newline at end of file
diff --git a/src/test/resources/oglycans_test_2.fasta b/src/test/resources/oglycans_test_2.fasta
new file mode 100644
index 0000000..659b02c
--- /dev/null
+++ b/src/test/resources/oglycans_test_2.fasta
@@ -0,0 +1,2 @@
+>0
+EEKPAVTAAPSK
\ No newline at end of file
diff --git a/~$README.md b/~$README.md
deleted file mode 100644
index 2bfd6a8..0000000
Binary files a/~$README.md and /dev/null differ