public List <MSFull> GetNext(int noSpectra) { List <MSFull> myScans = new List <MSFull>(noSpectra); string thisLine = ""; MSFull thisScan; if (cycleCounter == 0) { thisScan = new MSParser.MSFull(); } else { thisScan = bufferScan; } while (true) { thisLine = sr.ReadLine(); if (thisLine == null) { break; } if (thisLine.Length == 0) { continue; } if (isNumber.Match(thisLine, 0, 1).Success) { //We are dealing with MS ion data string[] ionData = mzSeparator.Split(thisLine); Ion ion = new Ion(double.Parse(ionData[0]), double.Parse(ionData[1]), thisScan.CromatographyRetentionTime, thisScan.ScanNumber); //Save our data thisScan.MSData.Add(ion); } else if (thisLine.StartsWith("Z")) { string[] theStrings3 = tabSeparator.Split(thisLine); if (thisScan.Charges == null) { thisScan.Charges = new List <int> { int.Parse(theStrings3[1]) }; thisScan.Precursors = new List <double> { double.Parse(theStrings3[2]) }; } else { thisScan.Charges.Add(int.Parse(theStrings3[1])); if (thisScan.Precursors == null) { thisScan.Precursors = new List <double>(); } thisScan.Precursors.Add(double.Parse(theStrings3[2])); } } else if (thisLine.Contains("ActivationType")) { string[] theStrings2 = tabSeparator.Split(thisLine); thisScan.ActivationType = theStrings2[2]; } else if (thisLine.Contains("InstrumentType")) { string[] theStrings2 = tabSeparator.Split(thisLine); thisScan.InstrumentType = theStrings2[2]; } else if (thisLine.Contains("RetTime")) { string[] theStrings2 = tabSeparator.Split(thisLine); if (theStrings2.Length == 2) { //The retention time is separated with a space so we need to further break it up string[] s = Regex.Split(theStrings2[1], @" "); thisScan.CromatographyRetentionTime = double.Parse(s[1]); } else if (theStrings2.Length == 3) { thisScan.CromatographyRetentionTime = double.Parse(theStrings2[2]); } else { throw new Exception("Problems parsing Retention time Line.\n" + thisLine); } } else if (thisLine.StartsWith("S")) { //Step 1:Save the Old One if (thisScan.MSData.Count > 0) //Make sure we dont have an empty scan! { myScans.Add(thisScan); } //Step 2:Get the new one ready thisScan = new MSParser.MSFull(); string[] theStrings = tabSeparator.Split(thisLine); thisScan.ScanNumber = int.Parse(theStrings[1]); thisScan.MSData = new List <Ion>(); if (theStrings.Length != 3) { //we are dealing with MS1 - the precursor shall be 0 //We are dealing with MS and should save precursor information thisScan.ChargedPrecursor = double.Parse(theStrings[3]); } if (myScans.Count == noSpectra) { bufferScan = thisScan; break; } } } if (thisLine == null) { sr.Close(); } cycleCounter++; return(myScans); }
public void ParseFile(FileInfo file, double minimumIonIntensity) { //Get the file to RAM myScans.Clear(); headerLines.Clear(); ParsedFileInfo = file; StreamReader sr = new StreamReader(file.OpenRead()); string thisLine; MSFile thisFile = new MSFile(); thisFile.FileName = file.Name; int lineCounter = 0; //Helps to debug. MSParser.MSFull thisScan = new MSParser.MSFull(); while ((thisLine = sr.ReadLine()) != null) { lineCounter++; if (thisLine.Length == 0) { continue; } if (isNumber.Match(thisLine, 0, 1).Success) { //We are dealing with MS ion data string[] ionData = mzSeparator.Split(thisLine); Ion ion = new Ion(double.Parse(ionData[0]), double.Parse(ionData[1]), thisScan.CromatographyRetentionTime, thisScan.ScanNumber); //Save our data thisScan.MSData.Add(ion); } else if (thisLine.StartsWith("H")) { headerLines.Add(thisLine); } else if (thisLine.StartsWith("Z")) { string[] theStrings3 = tabSeparator.Split(thisLine); if (thisScan.Charges == null) { thisScan.Charges = new List<int> { int.Parse(theStrings3[1]) }; thisScan.Precursors = new List<double> { double.Parse(theStrings3[2]) }; } else { thisScan.Charges.Add(int.Parse(theStrings3[1])); if (thisScan.Precursors == null) { thisScan.Precursors = new List<double>(); } thisScan.Precursors.Add(double.Parse(theStrings3[2])); } } else if (thisLine.Contains("ActivationType")) { string[] theStrings2 = tabSeparator.Split(thisLine); thisScan.ActivationType = theStrings2[2]; } else if (thisLine.Contains("InstrumentType")) { string[] theStrings2 = tabSeparator.Split(thisLine); thisScan.InstrumentType = theStrings2[2]; } else if (thisLine.Contains("RetTime")) { string[] theStrings2 = tabSeparator.Split(thisLine); if (theStrings2.Length == 2) { //The retention time is separated with a space so we need to further break it up string[] s = Regex.Split(theStrings2[1], @" "); thisScan.CromatographyRetentionTime = double.Parse(s[1]); } else if (theStrings2.Length == 3) { thisScan.CromatographyRetentionTime = double.Parse(theStrings2[2]); } else { throw new Exception("Problems parsing Retention time Line.\n" + thisLine); } } else if (thisLine.StartsWith("S")) { //We have a new spectra // scan //Denoise our scan thisScan.MSData.RemoveAll(p => p.Intensity < minimumIonIntensity); //Compute the ion intensity foreach (var scan in thisScan.MSData) { thisScan.TotalIonIntensity += scan.Intensity; } //Step 1:Save the Old One if (thisScan.MSData.Count > 0) //Make sure we dont have an empty scan! { myScans.Add(thisScan); } //Step 2:Get the new one ready thisScan = new MSParser.MSFull(); thisScan.TotalIonIntensity = 0; string[] theStrings = tabSeparator.Split(thisLine); thisScan.ScanNumber = int.Parse(theStrings[1]); thisScan.MSData = new List<Ion>(); if (theStrings.Length != 3) { //we are dealing with MS1 - the precursor shall be 0 //We are dealing with MS and should save precursor information thisScan.ChargedPrecursor = double.Parse(theStrings[3]); } } } //Save our last scan myScans.Add(thisScan); sr.Close(); }
/// <summary> /// If we dont fint any precursor, we will return 0; this method will only search for 3's and 2's /// </summary> /// <param name="percentileTolerance">Suggested 0.05</param> /// <param name="ppmTolerance"></param> /// <param name="thePeaks"></param> /// <returns></returns> public static Ion FindPrecursorAndCharge(double percentileTolerance, double ppmTolerance, List <Ion> thePeaks, bool considerCharge2) { Ion precursor = new Ion(0, 0, 0, 0); if (thePeaks.Count <= 50) { return(precursor); } if (percentileTolerance > 1 || percentileTolerance < 0) { throw (new Exception("Percentile tolerance out of bounds; use the recomended 0.95")); } thePeaks.Sort((a, b) => b.Intensity.CompareTo(a.Intensity)); int chopper = (int)Math.Round((double)thePeaks.Count * percentileTolerance); List <Ion> mostIntensePeaks = new List <Ion>(chopper); for (int i = 0; i < chopper; i++) { mostIntensePeaks.Add(thePeaks[i]); } if (mostIntensePeaks.Count < 10) { return(precursor); } mostIntensePeaks.Sort((a, b) => a.MZ.CompareTo(b.MZ)); Ion chosenPeak = mostIntensePeaks[0]; //and just a tweak lets find if there is a higher peak within a 5 da range for (int i = 0; i < mostIntensePeaks.Count; i++) { if (mostIntensePeaks[i].Intensity > chosenPeak.Intensity && Math.Abs(chosenPeak.MZ - mostIntensePeaks[i].MZ) < 7) { chosenPeak = mostIntensePeaks[i]; } } //Now lets verify if there is signal for a charge 2, 3, 4 for this peak; the signal must be at least 10% of the precursor //For the 4 charge, we will search for 3 and 2, if we dont find nothing, we try the 3, then the two, since the signal is more limited. //We shal not try higher charges since they are less likey to happen so we could be introducing false positives double CRP3to2 = (chosenPeak.MZ * 3 - 1) / 2; double CRP2to1 = (chosenPeak.MZ * 2) - 1; double CRP3to2Acumulator = 0; double CRP2to1Acumulator = 0; for (int i = 0; i < mostIntensePeaks.Count; i++) { if (PatternTools.pTools.PPM(CRP3to2, mostIntensePeaks[i].MZ) < ppmTolerance) { CRP3to2Acumulator += mostIntensePeaks[i].Intensity; } else if (PatternTools.pTools.PPM(CRP2to1, mostIntensePeaks[i].MZ) < ppmTolerance) { CRP2to1Acumulator += mostIntensePeaks[i].Intensity; } } if (CRP3to2Acumulator > chosenPeak.Intensity * 0.15) { precursor = new Ion(chosenPeak.MZ, chosenPeak.Intensity, chosenPeak.RetentionTime, 0); precursor.Charge = 3; } else if (CRP2to1Acumulator > mostIntensePeaks[0].Intensity * 0.2) { precursor = new Ion(chosenPeak.MZ, chosenPeak.Intensity, chosenPeak.RetentionTime, 0); precursor.Charge = 2; } //Make sure we get the peaks back in order by mz thePeaks.Sort((a, b) => a.MZ.CompareTo(b.MZ)); if ((precursor.Charge == 2 && considerCharge2) || precursor.Charge > 2) { return(precursor); } else { return(new Ion(0, 0, 0, 0)); } }
/// <summary> /// Careful! Works only for ions of charge 2 /// </summary> public static List <Ion> ETDComplementaryIons3(List <Ion> theSpectra, double ppm, Ion precursor, double minimumComplementaryIntensity) { List <Ion> cleanedMS = new List <Ion>(); //if the ion is a charge two, //Lets assume that both fragments have charge +1 double predictedPrecursorSumWithProtons = (precursor.MZ * 3) - 1.008; for (int i = 0; i < theSpectra.Count; i++) { if (theSpectra[i].Intensity < minimumComplementaryIntensity) { continue; } for (int j = 0; j < theSpectra.Count; j++) //Lets associate j with list 2; { double massSum = (theSpectra[i].MZ + theSpectra[j].MZ); if (massSum > (predictedPrecursorSumWithProtons + 2)) { break; } if (PatternTools.pTools.PPM(massSum, predictedPrecursorSumWithProtons) < ppm) { if (!cleanedMS.Contains(theSpectra[i])) { cleanedMS.Add(theSpectra[i]); } if (!cleanedMS.Contains(theSpectra[j])) { cleanedMS.Add(theSpectra[j]); } } } } return(cleanedMS); }