/// <summary> /// Generate centroids from two arrays of m/z and intensity /// </summary> /// <param name="scan"></param> /// <param name="mzArray"></param> /// <param name="intensityArray"></param> public void CentroidsFromArrays(Data.Scan scan, double[] mzArray, double[] intensityArray, double[] baseline = null, double[] noise = null) { if (mzArray.Length != intensityArray.Length) { throw new Exception(" Error: MZ and Intensity Arrays of unequal length."); } scan.PeakCount = mzArray.Length; for (int i = 0; i < mzArray.Length; i++) { Centroid tempCentroid = new Centroid() { Mz = mzArray[i], Intensity = intensityArray[i], }; if (baseline != null) { tempCentroid.Baseline = baseline[i]; } if (noise != null) { tempCentroid.Noise = noise[i]; } scan.Centroids.Add(tempCentroid); } }
/// <summary> /// Read the precursor scan number for a given scan. /// This is a fallback method since it's preferred to get the value /// from the "Master Scan Number" field in the scan header. /// </summary> /// <param name="scan">The scan that needs the assignment of the parent scan number</param> private void SetPrecursorScanNumber(Data.Scan scan) { if (ScanParents.Count == 0) { // Populate the index - this can be slow. ReadScanParents(); } if (ScanParents.ContainsKey(scan.ScanNumber)) { scan.PrecursorMasterScanNumber = ScanParents[scan.ScanNumber]; } }
/// <summary> /// Read the precursor scan number for a given scan. /// This is a fallback method since it's preferred to get the value /// from the "Master Scan Number" field in the scan header. /// </summary> /// <param name="scan">The scan that needs the assignment of the parent scan number</param> private void SetPrecursorScanNumber(Data.Scan scan) { if (!ScanParentsLoaded) { // Populate the index - this can be slow. ReadScanParents(); } if (ScanParents.ContainsKey(scan.ScanNumber)) { scan.PrecursorMasterScanNumber = ScanParents[scan.ScanNumber]; } // At this point there is no parent scan information. // Using the last MS1 doesnt work will for instruments that // acquire scans in parallel. scan.PrecursorMasterScanNumber = LastMS1; }
/// <summary> /// Open the given file and import scans into the reader. /// </summary> /// <returns></returns> public System.Collections.IEnumerator GetEnumerator() { rawFile.SelectInstrument(ThermoBiz.Device.MS, 1); // Get the first and last scan from the RAW file int FirstScan = rawFile.RunHeaderEx.FirstSpectrum; int LastScan = rawFile.RunHeaderEx.LastSpectrum; for (int iScanNumber = FirstScan; iScanNumber <= LastScan; iScanNumber++) { ThermoBiz.Scan thermoScan = ThermoBiz.Scan.FromFile(rawFile, iScanNumber); IScanFilter scanFilter = rawFile.GetFilterForScanNumber(iScanNumber); IScanEvent scanEvent = rawFile.GetScanEventForScanNumber(iScanNumber); if ((int)scanFilter.MSOrder == 1) { LastMS1 = iScanNumber; } Data.Scan scan = new Data.Scan() { ScanNumber = iScanNumber, ScanEvent = (iScanNumber - LastMS1) + 1, BasePeakIntensity = thermoScan.ScanStatistics.BasePeakIntensity, BasePeakMz = thermoScan.ScanStatistics.BasePeakMass, TotalIonCurrent = thermoScan.ScanStatistics.TIC, LowestMz = thermoScan.ScanStatistics.LowMass, HighestMz = thermoScan.ScanStatistics.HighMass, StartMz = scanFilter.GetMassRange(0).Low, EndMz = scanFilter.GetMassRange(0).High, ScanType = ReadScanType(scanFilter.ToString()), MsOrder = (int)scanFilter.MSOrder, Polarity = (scanFilter.Polarity == PolarityType.Positive) ? Data.Polarity.Positive : Data.Polarity.Negative, FilterLine = scanFilter.ToString(), DetectorType = readDetectorType(scanFilter.MassAnalyzer), RetentionTime = rawFile.RetentionTimeFromScanNumber(iScanNumber) }; if (scan.MsOrder > 1) { // Get the current scan's activation method while ignoring upstream activation scan.PrecursorActivationMethod = ConvertActivationType(scanFilter.GetActivation(scan.MsOrder - 2)); // handle dependent scans and not SPS (processed below) scan.Precursors.Clear(); for (int i = 0; i < scanEvent.MassCount; ++i) { var reaction = scanEvent.GetReaction(i); scan.CollisionEnergy = reaction.CollisionEnergy; var precursor = new Data.Precursor { IsolationWidth = reaction.IsolationWidth, IsolationMz = reaction.PrecursorMass, Mz = reaction.PrecursorMass, OriginalMz = reaction.PrecursorMass }; scan.Precursors.Add(precursor); } } ThermoBiz.RunHeader runHeader = rawFile.RunHeader; ThermoBiz.LogEntry trailer = rawFile.GetTrailerExtraInformation(iScanNumber); for (int i = 0; i < trailer.Length; i++) { var value = trailer.Values[i]; if (value == null) { continue; } switch (trailer.Labels[i]) { case "Access ID": int access_id = Convert.ToInt32(value); if (access_id > 0) { scan.PrecursorMasterScanNumber = access_id; } break; case "Scan Description:": scan.Description = value.Trim(); break; case "Ion Injection Time (ms):": scan.IonInjectionTime = double.Parse(value); break; case "Elapsed Scan Time (sec):": scan.ElapsedScanTime = double.Parse(value); break; case "Charge State:": int charge = int.Parse(value); foreach (var precursor in scan.Precursors) { precursor.Charge = charge; precursor.OriginalCharge = precursor.Charge; } break; case "Master Scan Number:": scan.PrecursorMasterScanNumber = int.Parse(value); break; case "Master Index:": scan.MasterIndex = int.Parse(value); break; case "Monoisotopic M/Z:": if (Options.RawMonoMz && scan.Precursors.Count > 0) { double mz = double.Parse(value); if (mz > 0) { scan.Precursors[0].Mz = mz; } } break; case "FAIMS CV:": scan.FaimsCV = (int)double.Parse(value); break; case "FAIMS Voltage On:": scan.FaimsState = (value == "No") ? Data.TriState.Off : Data.TriState.On; break; case "SPS Masses:": string[] spsIonStringArray = value.TrimEnd(',').Split(','); if (!string.IsNullOrWhiteSpace(spsIonStringArray[0]) && spsIonStringArray.Length > 0) { scan.Precursors.Clear(); for (int spsIndex = 0; spsIndex < spsIonStringArray.Length; spsIndex++) { if (double.TryParse(spsIonStringArray[spsIndex], out double spsIon)) { scan.Precursors.Add(new Data.Precursor(spsIon, 0, 1)); } } } break; } } if (scan.PrecursorMasterScanNumber <= 0 && scan.MsOrder > 1) { // Try again to set the precursor scan. SetPrecursorScanNumber(scan); } if (scan.MsOrder > 1 && scan.PrecursorMasterScanNumber > rawFile.RunHeader.FirstSpectrum && scan.PrecursorMasterScanNumber < rawFile.RunHeader.LastSpectrum) { // Fill precursor information var parentScan = ThermoBiz.Scan.FromFile(rawFile, scan.PrecursorMasterScanNumber); if (parentScan != null) { foreach (var precursor in scan.Precursors) { precursor.Intensity = GetMaxIntensity(parentScan, precursor.IsolationMz, precursor.IsolationWidth); } } } if (thermoScan.HasCentroidStream) { // High res data CentroidsFromArrays(scan, thermoScan.CentroidScan.Masses, thermoScan.CentroidScan.Intensities, thermoScan.CentroidScan.Baselines, thermoScan.CentroidScan.Noises); } else { // Low res data CentroidsFromArrays(scan, thermoScan.PreferredMasses, thermoScan.PreferredIntensities); } if (scan.PeakCount > 0) { scan.LowestMz = scan.Centroids[0].Mz; scan.HighestMz = scan.Centroids[scan.PeakCount - 1].Mz; } yield return(scan); } }