PSPtmScores peptideScores = new PSPtmScores();
PSParameter psParameter = new PSParameter();
HashMap<Double, Integer> variableModifications = new HashMap<Double, Integer>();
Peptide peptide = peptideMatch.getTheoreticPeptide();
ArrayList<ModificationMatch> originalMatches = peptide.getModificationMatches();
ArrayList<ModificationMatch> newModificationMatches = new ArrayList<ModificationMatch>(originalMatches.size());
HashMap<Double, ArrayList<Integer>> inferredSites = new HashMap<Double, ArrayList<Integer>>();
String originalKey = peptide.getMatchingKey(sequenceMatchingPreferences);
for (ModificationMatch modificationMatch : originalMatches) {
if (modificationMatch.isVariable()) {
PTM ptm = ptmFactory.getPTM(modificationMatch.getTheoreticPtm());
if (ptm.getType() == PTM.MODAA) {
Double ptmMass = ptm.getMass();
Integer nPtm = variableModifications.get(ptmMass);
if (nPtm == null) {
variableModifications.put(ptmMass, 1);
} else {
variableModifications.put(ptmMass, nPtm + 1);
}
if (modificationMatch.isInferred()) {
Integer modificationSite = modificationMatch.getModificationSite();
ArrayList<Integer> ptmInferredSites = inferredSites.get(ptmMass);
if (ptmInferredSites == null) {
ptmInferredSites = new ArrayList<Integer>();
inferredSites.put(ptmMass, ptmInferredSites);
ptmInferredSites.add(modificationSite);
} else if (!ptmInferredSites.contains(modificationSite)) {
ptmInferredSites.add(modificationSite);
}
}
} else {
newModificationMatches.add(modificationMatch);
}
} else {
newModificationMatches.add(modificationMatch);
}
}
HashMap<Double, ArrayList<ModificationMatch>> newMatches = new HashMap<Double, ArrayList<ModificationMatch>>(variableModifications.size());
if (variableModifications.size() > 0) {
ArrayList<String> bestKeys = new ArrayList<String>();
identification.loadSpectrumMatches(peptideMatch.getSpectrumMatches(), null);
identification.loadSpectrumMatchParameters(peptideMatch.getSpectrumMatches(), psParameter, null);
boolean validated = false;
for (String spectrumKey : peptideMatch.getSpectrumMatches()) {
psParameter = (PSParameter) identification.getSpectrumMatchParameter(spectrumKey, psParameter);
MatchValidationLevel matchValidationLevel = psParameter.getMatchValidationLevel();
if (matchValidationLevel.isValidated() && !validated) {
bestKeys.clear();
validated = true;
}
bestKeys.add(spectrumKey);
}
identification.loadSpectrumMatches(bestKeys, null);
identification.loadSpectrumMatchParameters(bestKeys, psParameter, null);
HashMap<Double, ArrayList<Integer>> confidentSites = new HashMap<Double, ArrayList<Integer>>();
// Map confident sites
for (String spectrumKey : bestKeys) {
psParameter = (PSParameter) identification.getSpectrumMatchParameter(spectrumKey, psParameter);
SpectrumMatch spectrumMatch = identification.getSpectrumMatch(spectrumKey);
PSPtmScores psmScores = (PSPtmScores) spectrumMatch.getUrParam(new PSPtmScores());
for (String ptmName : psmScores.getScoredPTMs()) {
PtmScoring psmScoring = psmScores.getPtmScoring(ptmName);
PtmScoring peptideScoring = peptideScores.getPtmScoring(ptmName);
if (peptideScoring == null) {
peptideScoring = new PtmScoring(ptmName);
peptideScores.addPtmScoring(ptmName, peptideScoring);
}
for (int site : psmScoring.getAllPtmLocations()) {
double psmDScore = psmScoring.getDeltaScore(site);
double peptideDScore = peptideScoring.getDeltaScore(site);
if (peptideDScore < psmDScore) {
peptideScoring.setDeltaScore(site, psmDScore);
}
double psmPScore = psmScoring.getProbabilisticScore(site);
double peptidePScore = peptideScoring.getProbabilisticScore(site);
if (peptidePScore < psmPScore) {
peptideScoring.setProbabilisticScore(site, psmPScore);
}
int psmValidationLevel = psmScoring.getLocalizationConfidence(site);
int peptideValidationLevel = peptideScoring.getLocalizationConfidence(site);
if (peptideValidationLevel < psmValidationLevel) {
peptideScoring.setSiteConfidence(site, psmValidationLevel);
}
}
}
for (Integer confidentSite : psmScores.getConfidentSites()) {
for (String ptmName : psmScores.getConfidentModificationsAt(confidentSite)) {
PTM ptm = ptmFactory.getPTM(ptmName);
Double ptmMass = ptm.getMass();
ArrayList<Integer> ptmConfidentSites = confidentSites.get(ptmMass);
if (ptmConfidentSites == null) {
ptmConfidentSites = new ArrayList<Integer>();
confidentSites.put(ptmMass, ptmConfidentSites);
}
if (!ptmConfidentSites.contains(confidentSite)) {
ptmConfidentSites.add(confidentSite);
peptideScores.addConfidentModificationSite(ptmName, confidentSite);
ModificationMatch newMatch = new ModificationMatch(ptmName, true, confidentSite);
newMatch.setConfident(true);
ArrayList<ModificationMatch> newPtmMatches = newMatches.get(ptmMass);
if (newPtmMatches == null) {
newPtmMatches = new ArrayList<ModificationMatch>();
newMatches.put(ptmMass, newPtmMatches);
}
newPtmMatches.add(newMatch);
if (newPtmMatches.size() > variableModifications.get(ptmMass)) {
throw new IllegalArgumentException("More sites than PTMs on peptide " + peptideMatch.getKey() + " for PTM of mass " + ptmMass + ".");
}
ArrayList<Integer> ptmInferredSites = inferredSites.get(ptmMass);
if (ptmInferredSites != null) {
ptmInferredSites.remove(confidentSite);
if (ptmInferredSites.isEmpty()) {
inferredSites.remove(ptmMass);
}
}
}
}
}
}
boolean enoughSites = true;
for (double ptmMass : variableModifications.keySet()) {
int nPtms = variableModifications.get(ptmMass);
int nConfident = 0;
ArrayList<Integer> ptmConfidentSites = confidentSites.get(ptmMass);
if (ptmConfidentSites != null) {
nConfident = ptmConfidentSites.size();
}
if (nConfident < nPtms) {
enoughSites = false;
break;
}
}
if (!enoughSites) {
HashMap<Double, HashMap<Double, HashMap<Double, HashMap<Integer, ArrayList<String>>>>> ambiguousSites = new HashMap<Double, HashMap<Double, HashMap<Double, HashMap<Integer, ArrayList<String>>>>>();
for (String spectrumKey : bestKeys) {
psParameter = (PSParameter) identification.getSpectrumMatchParameter(spectrumKey, psParameter);
SpectrumMatch spectrumMatch = identification.getSpectrumMatch(spectrumKey);
PSPtmScores psmScores = (PSPtmScores) spectrumMatch.getUrParam(new PSPtmScores());
for (int representativeSite : psmScores.getRepresentativeSites()) {
HashMap<Integer, ArrayList<String>> ambiguousMappingAtSite = psmScores.getAmbiguousPtmsAtRepresentativeSite(representativeSite);
int mappingSize = ambiguousMappingAtSite.size();
for (int site : ambiguousMappingAtSite.keySet()) {
for (String ptmName : ambiguousMappingAtSite.get(site)) {
PTM ptm = ptmFactory.getPTM(ptmName);
Double ptmMass = ptm.getMass();
ArrayList<Integer> ptmConfidentSites = confidentSites.get(ptmMass);
if (ptmConfidentSites == null || !ptmConfidentSites.contains(site)) {
double probabilisticScore = 0.0;
double dScore = 0.0;
PtmScoring ptmScoring = psmScores.getPtmScoring(ptmName);
if (ptmScoring != null) {
probabilisticScore = ptmScoring.getProbabilisticScore(site);
dScore = ptmScoring.getDeltaScore(site);
}
HashMap<Double, HashMap<Double, HashMap<Integer, ArrayList<String>>>> pScoreMap = ambiguousSites.get(probabilisticScore);
if (pScoreMap == null) {
pScoreMap = new HashMap<Double, HashMap<Double, HashMap<Integer, ArrayList<String>>>>(mappingSize);
ambiguousSites.put(probabilisticScore, pScoreMap);
}
HashMap<Double, HashMap<Integer, ArrayList<String>>> dScoreMap = pScoreMap.get(dScore);
if (dScoreMap == null) {
dScoreMap = new HashMap<Double, HashMap<Integer, ArrayList<String>>>(mappingSize);
pScoreMap.put(dScore, dScoreMap);
}
HashMap<Integer, ArrayList<String>> ptmMap = dScoreMap.get(ptmMass);
if (ptmMap == null) {
ptmMap = new HashMap<Integer, ArrayList<String>>(1);
dScoreMap.put(ptmMass, ptmMap);
}
ArrayList<String> modifications = ptmMap.get(site);
if (modifications == null) {
modifications = new ArrayList<String>(1);
ptmMap.put(site, modifications);
}
if (!modifications.contains(ptmName)) {
modifications.add(ptmName);
}
}
}
}
}
}
HashMap<Double, Integer> nRepresentativesMap = new HashMap<Double, Integer>();
for (double ptmMass : variableModifications.keySet()) {
int nPtm = variableModifications.get(ptmMass);
int nConfident = 0;
ArrayList<Integer> ptmConfidentSites = confidentSites.get(ptmMass);
if (ptmConfidentSites != null) {
nConfident = ptmConfidentSites.size();
}
if (nConfident < nPtm) {
int nRepresentatives = nPtm - nConfident;
if (nRepresentatives > 0) {
nRepresentativesMap.put(ptmMass, nRepresentatives);
}
}
}
HashMap<Double, HashMap<Integer, HashMap<Integer, ArrayList<String>>>> representativeToSecondaryMap = getRepresentativeToSecondaryMap(ambiguousSites, nRepresentativesMap, inferredSites);
for (Double ptmMass : representativeToSecondaryMap.keySet()) {
HashMap<Integer, HashMap<Integer, ArrayList<String>>> representativesAtMass = representativeToSecondaryMap.get(ptmMass);
ArrayList<Integer> ptmInferredSites = inferredSites.get(ptmMass);
for (int representativeSite : representativesAtMass.keySet()) {
HashMap<Integer, ArrayList<String>> siteToPtmMap = representativesAtMass.get(representativeSite);
peptideScores.addAmbiguousModificationSites(representativeSite, siteToPtmMap);
for (String ptmName : siteToPtmMap.get(representativeSite)) {
ModificationMatch newMatch = new ModificationMatch(ptmName, true, representativeSite);
newMatch.setConfident(false);
if (ptmInferredSites != null && ptmInferredSites.contains(representativeSite)) {
newMatch.setInferred(true);
}
ArrayList<ModificationMatch> newPtmMatches = newMatches.get(ptmMass);
if (newPtmMatches == null) {
newPtmMatches = new ArrayList<ModificationMatch>();
newMatches.put(ptmMass, newPtmMatches);
}
newPtmMatches.add(newMatch);
if (newPtmMatches.size() > variableModifications.get(ptmMass)) {
throw new IllegalArgumentException("More sites than PTMs on peptide " + peptideMatch.getKey() + " for PTM of mass " + ptmMass + ".");
}
}
}
}
}
for (ArrayList<ModificationMatch> modificationMatches : newMatches.values()) {
newModificationMatches.addAll(modificationMatches);
}
peptide.setModificationMatches(newModificationMatches);
peptideMatch.addUrParam(peptideScores);
String newKey = peptide.getMatchingKey(sequenceMatchingPreferences);
if (!newKey.equals(originalKey)) {
if (identification.getPeptideIdentification().contains(newKey)) {
throw new IllegalArgumentException("Attempting to create duplicate peptide key: " + newKey + ".");
}
identification.updatePeptideMatch(originalKey, newKey, peptideMatch);