String peptideSequence = peptide.getSequence();
// map the algorithm specific modifications on utilities modifications
// If there are not enough sites to put them all on the sequence, add an unknown modifcation
// Note: this needs to be done for tag based assumptions as well since the protein mapping can return erroneous modifications for some pattern based PTMs
ModificationProfile modificationProfile = searchParameters.getModificationProfile();
boolean fixedPtmIssue = false;
try {
ptmFactory.checkFixedModifications(modificationProfile, peptide, sequenceMatchingPreferences);
} catch (IllegalArgumentException e) {
if (idFilter.removeUnknownPTMs()) {
// Exclude peptides with aberrant PTM mapping
System.out.println(e.getMessage());
spectrumMatch.removeAssumption(assumption);
ptmIssue++;
fixedPtmIssue = true;
} else {
throw e;
}
}
if (!fixedPtmIssue) {
HashMap<Integer, ArrayList<String>> expectedNames = new HashMap<Integer, ArrayList<String>>();
HashMap<ModificationMatch, ArrayList<String>> modNames = new HashMap<ModificationMatch, ArrayList<String>>();
for (ModificationMatch modMatch : peptide.getModificationMatches()) {
HashMap<Integer, ArrayList<String>> tempNames = new HashMap<Integer, ArrayList<String>>();
if (modMatch.isVariable()) {
String sePTM = modMatch.getTheoreticPtm();
if (fileReader instanceof OMSSAIdfileReader) {
Integer omssaIndex = null;
try {
omssaIndex = new Integer(sePTM);
} catch (Exception e) {
waitingHandler.appendReport("Impossible to parse OMSSA modification " + sePTM + ".", true, true);
}
if (omssaIndex != null) {
String omssaName = modificationProfile.getModification(omssaIndex);
if (omssaName == null) {
if (!ignoredOMSSAModifications.contains(omssaIndex)) {
waitingHandler.appendReport("Impossible to find OMSSA modification of index "
+ omssaIndex + ". The corresponding peptides will be ignored.", true, true);
ignoredOMSSAModifications.add(omssaIndex);
}
omssaName = PTMFactory.unknownPTM.getName();
}
tempNames = ptmFactory.getExpectedPTMs(modificationProfile, peptide, omssaName, ptmMassTolerance, sequenceMatchingPreferences);
}
} else if (fileReader instanceof MascotIdfileReader
|| fileReader instanceof XTandemIdfileReader
|| fileReader instanceof MsAmandaIdfileReader
|| fileReader instanceof MzIdentMLIdfileReader
|| fileReader instanceof PepxmlIdfileReader) {
String[] parsedName = sePTM.split("@");
double seMass = 0;
try {
seMass = new Double(parsedName[0]);
} catch (Exception e) {
throw new IllegalArgumentException("Impossible to parse \'" + sePTM + "\' as a tagged modification.\n"
+ "Error encountered in peptide " + peptideSequence + " spectrum " + spectrumTitle + " in spectrum file " + fileName + ".\n"
+ "Identification file: " + idFile.getName());
}
tempNames = ptmFactory.getExpectedPTMs(modificationProfile, peptide, seMass, ptmMassTolerance, sequenceMatchingPreferences);
} else if (fileReader instanceof DirecTagIdfileReader) {
PTM ptm = ptmFactory.getPTM(sePTM);
if (ptm == PTMFactory.unknownPTM) {
throw new IllegalArgumentException("PTM not recognized spectrum " + spectrumTitle + " of file " + fileName + ".");
}
tempNames = ptmFactory.getExpectedPTMs(modificationProfile, peptide, ptm.getMass(), ptmMassTolerance, sequenceMatchingPreferences);
} else {
throw new IllegalArgumentException("PTM mapping not implemented for the parsing of " + idFile.getName() + ".");
}
ArrayList<String> allNames = new ArrayList<String>();
for (ArrayList<String> namesAtAA : tempNames.values()) {
for (String name : namesAtAA) {
if (!allNames.contains(name)) {
allNames.add(name);
}
}
}
modNames.put(modMatch, allNames);
for (int pos : tempNames.keySet()) {
ArrayList<String> namesAtPosition = expectedNames.get(pos);
if (namesAtPosition == null) {
namesAtPosition = new ArrayList<String>(2);
expectedNames.put(pos, namesAtPosition);
}
for (String ptmName : tempNames.get(pos)) {
if (!namesAtPosition.contains(ptmName)) {
namesAtPosition.add(ptmName);
}
}
}
}
}
// If a terminal modification cannot be elsewhere lock the terminus
ModificationMatch nTermModification = null;
for (ModificationMatch modMatch : peptide.getModificationMatches()) {
if (modMatch.isVariable() && !modMatch.getTheoreticPtm().equals(PTMFactory.unknownPTM.getName())) {
double refMass = getRefMass(modMatch.getTheoreticPtm(), modificationProfile);
int modSite = modMatch.getModificationSite();
if (modSite == 1) {
ArrayList<String> expectedNamesAtSite = expectedNames.get(modSite);
if (expectedNamesAtSite != null) {
ArrayList<String> filteredNamesAtSite = new ArrayList<String>(expectedNamesAtSite.size());
for (String ptmName : expectedNamesAtSite) {
PTM ptm = ptmFactory.getPTM(ptmName);
if (Math.abs(ptm.getMass() - refMass) < searchParameters.getFragmentIonAccuracy()) {
filteredNamesAtSite.add(ptmName);
}
}
for (String modName : filteredNamesAtSite) {
PTM ptm = ptmFactory.getPTM(modName);
if (ptm.isNTerm()) {
boolean otherPossibleMod = false;
for (String tempName : modificationProfile.getAllNotFixedModifications()) {
if (!tempName.equals(modName)) {
PTM tempPTM = ptmFactory.getPTM(tempName);
if (tempPTM.getMass() == ptm.getMass() && !tempPTM.isNTerm()) {
otherPossibleMod = true;
break;
}
}
}
if (!otherPossibleMod) {
nTermModification = modMatch;
modMatch.setTheoreticPtm(modName);
break;
}
}
}
if (nTermModification != null) {
break;
}
}
}
}
}
ModificationMatch cTermModification = null;
for (ModificationMatch modMatch : peptide.getModificationMatches()) {
if (modMatch.isVariable() && !modMatch.getTheoreticPtm().equals(PTMFactory.unknownPTM.getName()) && modMatch != nTermModification) {
double refMass = getRefMass(modMatch.getTheoreticPtm(), modificationProfile);
int modSite = modMatch.getModificationSite();
if (modSite == peptideSequence.length()) {
ArrayList<String> expectedNamesAtSite = expectedNames.get(modSite);
if (expectedNamesAtSite != null) {
ArrayList<String> filteredNamesAtSite = new ArrayList<String>(expectedNamesAtSite.size());
for (String ptmName : expectedNamesAtSite) {
PTM ptm = ptmFactory.getPTM(ptmName);
if (Math.abs(ptm.getMass() - refMass) < searchParameters.getFragmentIonAccuracy()) {
filteredNamesAtSite.add(ptmName);
}
}
for (String modName : filteredNamesAtSite) {
PTM ptm = ptmFactory.getPTM(modName);
if (ptm.isCTerm()) {
boolean otherPossibleMod = false;
for (String tempName : modificationProfile.getAllNotFixedModifications()) {
if (!tempName.equals(modName)) {
PTM tempPTM = ptmFactory.getPTM(tempName);
if (tempPTM.getMass() == ptm.getMass() && !tempPTM.isCTerm()) {
otherPossibleMod = true;
break;