public static double CalculateForOneScan(CentroidStreamData Ms1Scan, double monoIsoMass, double isoWindow, int charge, double ppm = 4) { double[] masses; double[] intensities; double[] interferences; double currentIsotope; List <double> isotopes = new List <double>(); // subset the ms1 scan to be the isolation window (masses, intensities) = SubsetCentroidScan(Ms1Scan, monoIsoMass, isoWindow); // make a copy of the intensities array to represent the interference intensities interferences = (double[])intensities.Clone(); // make a list of the possible isotopes currentIsotope = monoIsoMass; while (currentIsotope < monoIsoMass + 0.5 * isoWindow) { isotopes.Add(currentIsotope); currentIsotope += 1.007276 / charge; } for (int i = 0; i < interferences.Length; i++) { double ion = masses[i]; if (isotopes.withinTolerance(ion, 4)) { interferences[i] = 0; } } return(interferences.Sum() / intensities.Sum()); }
public static List <int> GetChargeState(CentroidStreamData centroidData, double parentMass, int assignedCharge) { double[] masses; double[] intensities; int[] allowedCharges = new int[] { 2, 3, 4, 5 }; List <int> possibleChargeStates = new List <int>(); int parentIndex; double massDiff = 1.003356; (masses, intensities) = AdditionalMath.SubsetMsData(centroidData.Masses, centroidData.Intensities, parentMass - 0.1, parentMass + 1.2); if (masses.Length == 0) { possibleChargeStates.Add(assignedCharge); return(possibleChargeStates); } int currentIndex; if (masses.withinTolerance(parentMass, 10)) { parentIndex = masses.indexOfClosest(parentMass); } else { possibleChargeStates.Add(assignedCharge); return(possibleChargeStates); } // needs more work. can try matching multiple isotopes, then if charge state is ambiguous take the one with more matches foreach (int charge in allowedCharges) { currentIndex = parentIndex + 1; double isotopeMass = parentMass + massDiff / charge; for (int i = currentIndex; i < masses.Length; i++) { if (Math.Abs(masses[i] - isotopeMass) / isotopeMass * 1e6 < 6) { double ratio = intensities[i] / intensities[parentIndex]; if (ratio > 10 | ratio < 0.1) { // the peak is really big or small compared to the parent peak. it probably is not actually an isotope of it continue; } possibleChargeStates.Add(charge); break; } } } if (possibleChargeStates.Count() == 0) { possibleChargeStates.Add(assignedCharge); } return(possibleChargeStates); }
static (double[], double[]) SubsetCentroidScan(this CentroidStreamData Ms1Scan, double parentMass, double isoWindow) { List <double> masses = new List <double>(); List <double> intensities = new List <double>(); double lower = parentMass - 0.5 * isoWindow; double upper = parentMass + 0.5 * isoWindow; for (int i = 0; i < Ms1Scan.Masses.Length; i++) { if (Ms1Scan.Masses[i] > lower & Ms1Scan.Masses[i] < upper) { masses.Add(Ms1Scan.Masses[i]); intensities.Add(Ms1Scan.Intensities[i]); } } return(masses.ToArray(), intensities.ToArray()); }
public static (CentroidStreamCollection centroids, SegmentScanCollection segments) MsData(IRawDataPlus rawFile, ScanIndex index) { rawFile.SelectInstrument(Device.MS, 1); CentroidStreamCollection centroids = new CentroidStreamCollection(); SegmentScanCollection segments = new SegmentScanCollection(); CentroidStream centroid; SegmentedScan segment; var scans = index.allScans; //var lockTarget = new object(); // this is so we can keep track of progress in the parallel loop ProgressIndicator P = new ProgressIndicator(scans.Count(), "Extracting scan data"); P.Start(); foreach (int scan in scans.Keys) { // first get out the mass spectrum if (index.allScans[scan].MassAnalyzer == MassAnalyzerType.MassAnalyzerFTMS) { centroid = rawFile.GetCentroidStream(scan, false); centroids[scan] = new CentroidStreamData(centroid); } else { segment = rawFile.GetSegmentedScanFromScanNumber(scan, null); segments[scan] = new SegmentedScanData(segment); } //lock (lockTarget) //{ // P.Update(); //} P.Update(); } P.Done(); return(centroids, segments); }
// first instance method is for FTMS data static public QuantData QuantifyOneScan(CentroidStreamData centroidStream, string labelingReagent) { (string[] Labels, double[] Masses)reporters = new LabelingReagents().Reagents[labelingReagent]; QuantData quantData = new QuantData(); int index; double mass; double[] massDiff; for (int i = 0; i < reporters.Masses.Length; i++) { mass = reporters.Masses[i]; int[] indices = centroidStream.Masses.FindAllIndex1((x) => { if (Math.Abs(x - mass) / mass * 1e6 < 10) { return(true); } else { return(false); } }); if (indices.Length > 1) { massDiff = new double[indices.Length]; for (int ix = 0; ix < indices.Length; ix++) { massDiff[ix] = Math.Abs(centroidStream.Masses[indices[ix]] - mass); } index = -1; for (int j = 0; j < indices.Length; j++) { if (massDiff[j] == massDiff.Min()) { index = indices[j]; break; } else { continue; } } //index = Array.Find(indices, x => centroidStream.Masses[indices[x]] - mass == massDiff.Min()); if (index != -1) { quantData.Add(reporters.Labels[i], new ReporterIon(centroidStream.Masses[index], centroidStream.Intensities[index], centroidStream.Noises[index], centroidStream.Resolutions[index], centroidStream.Baselines[index], centroidStream.SignalToNoise[index], massDiff.Min() / mass * 1e6)); } else { quantData.Add(reporters.Labels[i], new ReporterIon(0, 0, 0, 0, 0, 0, 0)); } } else { if (indices.Length == 1) { index = indices.Single(); var diff = Math.Abs(centroidStream.Masses[index] - mass); quantData.Add(reporters.Labels[i], new ReporterIon(centroidStream.Masses[index], centroidStream.Intensities[index], centroidStream.Noises[index], centroidStream.Resolutions[index], centroidStream.Baselines[index], centroidStream.SignalToNoise[index], diff / mass * 1e6)); } else { quantData.Add(reporters.Labels[i], new ReporterIon(0, 0, 0, 0, 0, 0, 0)); } } } return(quantData); }
/// <summary> /// /// </summary> /// <param name="centroidData"></param> /// <param name="parentMZ"></param> /// <param name="possibleChargeStates"></param> /// <param name="assignedChargeState"></param> /// <returns></returns> static (int charge, double mass) GetMonoIsotopicMassCharge(CentroidStreamData centroidData, double parentMZ, List <int> possibleChargeStates, int assignedChargeState) { Dictionary <(int charge, double monoIsoMass), (double distance, double correlation)> scores = new Dictionary <(int charge, double monoIsoMass), (double distance, double correlation)>();; List <double> possibleMonoIsoMasses; Averagine averagine = new Averagine(); double[] masses, intensities; (masses, intensities) = AdditionalMath.SubsetMsData(centroidData.Masses, centroidData.Intensities, parentMZ - 2.2, parentMZ + 5); if (masses.Length == 0) { return(assignedChargeState, parentMZ); } foreach (int charge in possibleChargeStates) { // populate a list of possible monoisotopic masses possibleMonoIsoMasses = new List <double>() { parentMZ }; for (int i = 1; i < 4; i++) { double isotope = parentMZ - i * Masses.C13MinusC12 / charge; if (masses.withinTolerance(isotope, 10)) { possibleMonoIsoMasses.Add(isotope); } else { break; } } if (possibleChargeStates.Count() == 1 & possibleMonoIsoMasses.Count() == 1) { // only one possible monoisotopic mass was found, so just return that return(possibleChargeStates.First(), parentMZ); } // now score foreach (double monoisoMZ in possibleMonoIsoMasses) { // calculate the actual mass and intensity envelope of the potential monoisotopicMZ double monoIsotopeMass = (monoisoMZ - Masses.Proton) * charge; double[] isotopomerEnvelope = Averagine.GetIsotopomerEnvelope(monoIsotopeMass).Envelope; // get out the observed intensities corresponding to the isotope envelope List <double> observedIntensities = new List <double>(); int currentIndex = masses.ToList().IndexOf(monoisoMZ); for (int i = 0; i < isotopomerEnvelope.Count(); i++) { if ((masses.withinTolerance(monoisoMZ + i * Masses.C13MinusC12 / charge, 10))) { if (currentIndex < intensities.Count()) { int index = masses.indexOfClosest(monoisoMZ + i * Masses.C13MinusC12 / charge); observedIntensities.Add(intensities[index]); } else { // we've run out of ions double[] temp = new double[observedIntensities.Count()]; for (int j = 0; j < temp.Length; j++) { temp[j] = isotopomerEnvelope[j]; } isotopomerEnvelope = temp; } } else { observedIntensities.Add(0); } currentIndex++; } // normalize the observed intensities double maxInt = observedIntensities.Max(); for (int i = 0; i < observedIntensities.Count(); i++) { observedIntensities[i] = observedIntensities[i] / maxInt; } // calculate distance and correlation double distance, correlation; (distance, correlation) = FitScores.GetDistanceAndCorrelation(observedIntensities.ToArray(), isotopomerEnvelope); if (distance < 0.3) { scores.Add((charge, monoisoMZ), (distance, correlation)); } } } double smallestDistance = 1; double massOut = 0; int chargeOut = assignedChargeState; if (scores.Keys.Count == 0) { return(chargeOut, parentMZ); } foreach (var key in scores?.Keys) { if (scores[key].distance < smallestDistance) { smallestDistance = scores[key].distance; massOut = key.monoIsoMass; chargeOut = key.charge; } } return(chargeOut, massOut); }
/// <summary> /// Predict precursor monoisotopic mass /// </summary> /// <param name="centroidData">MS1 centroid data</param> /// <param name="parentMZ">Parent ion m/z</param> /// <param name="assignedCharge">Charge state assigned in the raw file</param> /// <returns></returns> static (int charge, double mass) GetMonoIsotopicMassCharge(CentroidStreamData centroidData, double parentMZ, int assignedCharge, int minCharge, int maxCharge) { List <int> possibleChargeStates = ChargeStateCalculator.GetChargeState(centroidData, parentMZ, assignedCharge, minCharge, maxCharge); return(GetMonoIsotopicMassCharge(centroidData, parentMZ, possibleChargeStates, assignedCharge)); }
public static void WriteMGF(RawDataCollection rawData, IRawDataPlus rawFile, string outputDirectory, double cutoff = 0, int[] scans = null, double intensityCutoff = 0.01) { double intCutoff = 0; string fileName = ReadWrite.GetPathToFile(outputDirectory, rawData.rawFileName, ".mgf"); MassAnalyzerType ms2MassAnalyzer = rawData.methodData.MassAnalyzers[MSOrderType.Ms2]; List <Operations> operations = new List <Operations> { Operations.ScanIndex, Operations.MethodData, Operations.TrailerExtras, Operations.RetentionTimes }; if (ms2MassAnalyzer == MassAnalyzerType.MassAnalyzerFTMS) { operations.Add(Operations.Ms2CentroidStreams); } else { operations.Add(Operations.Ms2SegmentedScans); } CheckIfDone.Check(rawData, rawFile, operations); const int BufferSize = 65536; // 64 Kilobytes using (StreamWriter f = new StreamWriter(fileName, false, Encoding.UTF8, BufferSize)) //Open a new file, the MGF file { // if the scans argument is null, use all scans if (scans == null) { scans = rawData.scanIndex.ScanEnumerators[MSOrderType.Ms2]; } ProgressIndicator progress = new ProgressIndicator(scans.Count(), String.Format("Writing MGF file")); foreach (int i in scans) { f.WriteLine("\nBEGIN IONS"); f.WriteLine("RAWFILE={0}", rawData.rawFileName); f.WriteLine("TITLE=Spectrum_{0}", i); f.WriteLine("SCAN={0}", i); f.WriteLine("RTINSECONDS={0}", rawData.retentionTimes[i]); f.WriteLine("PEPMASS={0}", rawData.trailerExtras[i].MonoisotopicMZ); f.WriteLine("CHARGE={0}", rawData.trailerExtras[i].ChargeState); if (ms2MassAnalyzer == MassAnalyzerType.MassAnalyzerFTMS) { CentroidStreamData centroid = rawData.centroidStreams[i]; if (centroid.Intensities.Length > 0) { intCutoff = centroid.Intensities.Max() * intensityCutoff; } else { intCutoff = 0; } for (int j = 0; j < centroid.Masses.Length; j++) { //f.WriteLine(Math.Round(centroid.Masses[j], 4).ToString() + " " + Math.Round(centroid.Intensities[j], 4).ToString()); if (centroid.Masses[j] > cutoff & centroid.Intensities[j] > intCutoff) { f.WriteLine("{0} {1}", Math.Round(centroid.Masses[j], 5), Math.Round(centroid.Intensities[j], 4)); } } } else { SegmentedScanData segments = rawData.segmentedScans[i]; if (segments.Intensities.Length > 0) { intCutoff = segments.Intensities.Max() * intensityCutoff; } else { intCutoff = 0; } for (int j = 0; j < segments.Positions.Length; j++) { if (segments.Positions[j] > cutoff & segments.Intensities[j] > intCutoff) { f.WriteLine("{0} {1}", Math.Round(segments.Positions[j], 5), Math.Round(segments.Intensities[j], 4)); } } } f.WriteLine("END IONS"); progress.Update(); } progress.Done(); } Utilities.ConsoleUtils.ClearLastLine(); }