//method was originally written recursively, but large peptides result in stackoverflow exceptions public void MassMatch(string B, string Y, PSM psm, int BIndex, int YIndex, out string error_message) //this is the workhorse of SpliceFragments { error_message = ""; test = psm.getScan().ToString(); double ExperimentalMass = psm.getExpMass(); string BFrag = IonCrop(B, ExperimentalMass, BIndex, IonType.b, false, out string e4); //returns a B ion sequence that has a mass smaller than the experimental mass by cleaving C term AA //BIndex = B.Length - BFrag.Length; //added 11/8/16 Useful first pass to record how many AA have been cleaved from C term string YFrag = IonCrop(Y, ExperimentalMass, YIndex, IonType.y, false, out string e3); //returns a Y ion sequence that has a mass smaller than the experimental mass by cleaving N term AA //YIndex = Y.Length - YFrag.Length; //added 11/8/16 Useful first pass to record how many AA have been cleaved from N term double TheoreticalMass = MassCalculator.MonoIsoptopicMass(BFrag, out string e) + MassCalculator.MonoIsoptopicMass(YFrag, out string e2) - Constants.WATER_MONOISOTOPIC_MASS + fixedModMass; //water added once in b and once in y error_message += e3 + e4 + e + e2; //add PTM masses foreach (PTM ptm in psm.getNInfo().getPTMs()) { if (ptm.index < BFrag.Length) { TheoreticalMass += ptm.mass; } } foreach (PTM ptm in psm.getCInfo().getPTMs()) { if (Y.Length - ptm.index < YFrag.Length) { TheoreticalMass += ptm.mass; } } if (YFrag.Length < ionsUsedMassVer) //If the number of AA from the C-term peptide is less than desired amount, end recursion. { //we're done } else if (BFrag.Length < ionsUsedMassVer) //If the number of AA from the N-term peptide is less than desired amount, start over loop and remove a single aa from the C-term { // MassMatch(B, Y, psm, 0, YIndex+1); } //if match //bool elif = true; //"else if" where not a match==true else if (FalsePositives.generateDecoys) { //else if (((TheoreticalMass - Constants.PEPTIDE_N_TERMINAL_MONOISOTOPIC_MASS * 7) > (ExperimentalMass - 1 * Constants.PEPTIDE_N_TERMINAL_MONOISOTOPIC_MASS) && (TheoreticalMass - Constants.PEPTIDE_N_TERMINAL_MONOISOTOPIC_MASS * 7) < (ExperimentalMass + 1 * Constants.PEPTIDE_N_TERMINAL_MONOISOTOPIC_MASS)) | ((TheoreticalMass + Constants.PEPTIDE_N_TERMINAL_MONOISOTOPIC_MASS * 7) > (ExperimentalMass - 1 * Constants.PEPTIDE_N_TERMINAL_MONOISOTOPIC_MASS) && (TheoreticalMass + Constants.PEPTIDE_N_TERMINAL_MONOISOTOPIC_MASS * 7) < (ExperimentalMass + 1 * Constants.PEPTIDE_N_TERMINAL_MONOISOTOPIC_MASS)))//if match //if ((TheoreticalMass) > (ExperimentalMass+ i -PrecursorMassToleranceDa) && (TheoreticalMass) < (ExperimentalMass+i +PrecursorMassToleranceDa)) //if match if (((TheoreticalMass) > (ExperimentalMass - 9.5) && (TheoreticalMass) < (ExperimentalMass - 4.5)) | ((TheoreticalMass) > (ExperimentalMass + 5.5) && (TheoreticalMass) < (ExperimentalMass + 7.5)))//if match //if ((TheoreticalMass) > (ExperimentalMass+ i -PrecursorMassToleranceDa) && (TheoreticalMass) < (ExperimentalMass+i +PrecursorMassToleranceDa)) //if match //else if(Math.Abs(ExperimentalMass - TheoreticalMass)<40 && (ExperimentalMass - TheoreticalMass)-Math.Floor(ExperimentalMass-TheoreticalMass)>0.3 && (ExperimentalMass - TheoreticalMass) - Math.Floor(ExperimentalMass - TheoreticalMass) < 0.8) { // elif = false; bool previouslyFound = false; foreach (FusionCandidate oldCandidate in psm.getFusionCandidates()) { if ((BFrag + YFrag).Equals(oldCandidate.seq)) //see if that sequence was already recorded { previouslyFound = true; } } if (!previouslyFound) //if fusion sequence was not previously assigned to this psm { FusionCandidate candidate = new FusionCandidate(BFrag + YFrag); psm.addFusionCandidate(candidate); // MassMatch(B, Y, psm, BIndex + 1, YIndex); } } } else { if ((TheoreticalMass) > (ExperimentalMass * (1 - FalsePositives.precursorMassTolerancePpm / 1000000)) && (TheoreticalMass) < (ExperimentalMass * (1 + FalsePositives.precursorMassTolerancePpm / 1000000))) //if match //if ((TheoreticalMass) > (ExperimentalMass+ i -PrecursorMassToleranceDa) && (TheoreticalMass) < (ExperimentalMass+i +PrecursorMassToleranceDa)) //if match { // elif = false; bool previouslyFound = false; foreach (FusionCandidate oldCandidate in psm.getFusionCandidates()) { if ((BFrag + YFrag).Equals(oldCandidate.seq)) //see if that sequence was already recorded { previouslyFound = true; } } if (!previouslyFound) //if fusion sequence was not previously assigned to this psm { FusionCandidate candidate = new FusionCandidate(BFrag + YFrag); psm.addFusionCandidate(candidate); // MassMatch(B, Y, psm, BIndex + 1, YIndex); } } } // if(elif) //not a match { /* if (TheoreticalMass < ExperimentalMass && BIndex == 0) //first pass, theo less than exp and can't take away more ions * { * //we're done * } * else * { * if (TheoreticalMass < ExperimentalMass) //if b out of ions, but y not, crop off a y and start again * { * BIndex = 0; * YIndex++; * MassMatch(B,Y, psm, BIndex, YIndex); * } * else * { //crop off a b ion * MassMatch(B, Y, psm, BIndex + 1, YIndex); * } * }*/ } }
//use ion hits to know where peaks have been found by morpheus and where there is ambiguity public static void findIons(FusionCandidate fusionCandidate, PSM psm, out string error_message) { error_message = ""; double[] nPeaks = psm.getNInfo().getPeakHits(); //get peaks double[] cPeaks = psm.getCInfo().getPeakHits(); fusionCandidate.makeFoundIons(); string candSeq = fusionCandidate.seq; bool[] foundIons = fusionCandidate.getFoundIons(); //find which aa have peaks for (int i = 0; i < foundIons.Count() - 1; i++) { //B IONS// if (ionsUsed.Contains(IonType.b)) { double bTheoMass = MassCalculator.MonoIsoptopicMass(candSeq.Substring(0, 1 + i), out string error_message2) - Constants.WATER_MONOISOTOPIC_MASS; error_message += error_message2; foreach (PTM ptm in psm.getNInfo().getPTMs()) { if (ptm.index <= i) { bTheoMass += ptm.mass; } } foreach (double expPeak in nPeaks) { if (expPeak > bTheoMass - productMassToleranceDa && expPeak < bTheoMass + productMassToleranceDa) { foundIons[i] = true; } } } //Y IONS// if (ionsUsed.Contains(IonType.y)) { double yTheoMass = MassCalculator.MonoIsoptopicMass(candSeq.Substring(candSeq.Length - 1 - i, i + 1), out string error_message3); error_message += error_message3; foreach (PTM ptm in psm.getCInfo().getPTMs()) { if (ptm.index >= candSeq.Length - 2 - i) { yTheoMass += ptm.mass; } } foreach (double expPeak in cPeaks) { if (expPeak > yTheoMass - productMassToleranceDa && expPeak < yTheoMass + productMassToleranceDa) { foundIons[foundIons.Count() - 2 - i] = true; } } } //C IONS// if (ionsUsed.Contains(IonType.c)) { double cTheoMass = MassCalculator.MonoIsoptopicMass(candSeq.Substring(0, 1 + i), out string error_message4) - Constants.WATER_MONOISOTOPIC_MASS + Constants.nitrogenMonoisotopicMass + 3 * Constants.hydrogenMonoisotopicMass; error_message += error_message4; foreach (PTM ptm in psm.getNInfo().getPTMs()) { if (ptm.index <= i) { cTheoMass += ptm.mass; } } foreach (double expPeak in nPeaks) { if (expPeak > cTheoMass - productMassToleranceDa && expPeak < cTheoMass + productMassToleranceDa) { foundIons[i] = true; } } } //ZDOT IONS// if (ionsUsed.Contains(IonType.zdot)) { double zdotTheoMass = MassCalculator.MonoIsoptopicMass(candSeq.Substring(candSeq.Length - 1 - i, i + 1), out string error_message5) - Constants.nitrogenMonoisotopicMass - 2 * Constants.hydrogenMonoisotopicMass; error_message += error_message5; foreach (PTM ptm in psm.getCInfo().getPTMs()) { if (ptm.index >= candSeq.Length - 2 - i) { zdotTheoMass += ptm.mass; } } foreach (double expPeak in cPeaks) { if (expPeak > zdotTheoMass - productMassToleranceDa && expPeak < zdotTheoMass + productMassToleranceDa) { foundIons[foundIons.Count() - 2 - i] = true; } } } } //foundIons[0] = true; //AspN always starts with a D foundIons[foundIons.Count() - 1] = true;//A|B|C|D|E|F|K| where the whole peptide peak is always placed arbitrarly at the c term }