예제 #1
0
        /// <summary>
        /// Shows or hides instrument Precursor m/z and mass from the instrument
        /// Reads data from LCMSRun if necessary
        /// </summary>
        /// <param name="value">Should the instrument data be shown?</param>
        /// <param name="pbfLcmsRun">LCMSRun for this data set.</param>
        /// <returns>Asynchronous task.</returns>
        public async Task ToggleShowInstrumentDataAsync(bool value, PbfLcMsRun pbfLcmsRun)
        {
            if (value)
            {
                if (pbfLcmsRun != null)
                {
                    var scans = this.Data;
                    foreach (var scan in scans.Where(scan => scan.Sequence.Count == 0))
                    {
                        PrSm            scan1           = scan;
                        IsolationWindow isolationWindow = await Task.Run(() => pbfLcmsRun.GetIsolationWindow(scan1.Scan));

                        scan.PrecursorMz = isolationWindow.MonoisotopicMz ?? double.NaN;
                        scan.Charge      = isolationWindow.Charge ?? 0;
                        scan.Mass        = isolationWindow.MonoisotopicMass ?? double.NaN;
                    }
                }
            }
            else
            {
                var scans = this.Data;
                foreach (var scan in scans.Where(scan => scan.Sequence.Count == 0))
                {
                    scan.PrecursorMz = double.NaN;
                    scan.Charge      = 0;
                    scan.Mass        = double.NaN;
                }
            }
        }
예제 #2
0
        /// <summary>
        /// Read a MZID results file asynchronously.
        /// </summary>
        /// <param name="modIgnoreList">Ignores modifications contained in this list.</param>
        /// <param name="progress">The progress reporter.</param>
        /// <returns>Identification tree of MZID identifications.</returns>
        public async Task <IEnumerable <PrSm> > ReadAsync(IEnumerable <string> modIgnoreList = null, IProgress <double> progress = null)
        {
            var dataset = await Task.Run(() => mzIdentMlReader.Read(filePath));

            var prsmList       = new List <PrSm>();
            var sequenceReader = new SequenceReader();

            foreach (var mod in dataset.SearchModifications)
            {
                if (mod.Name.Equals("unknown modification", StringComparison.OrdinalIgnoreCase))
                {
                    continue;
                }

                if (Modification.Get(mod.Name) == null)
                {
                    // Add the modification to the list, with an unspecified accession number
                    var modData = new Modification(0, mod.Mass, mod.Name);
                    Modification.Register(modData);
                    // Could use IcParameters.Instance.RegisterModification, but we want to support whatever the name in the file is, regardless of if the mass is a duplicate.
                    IcParameters.Instance.RegisteredModifications.Add(modData);
                }
            }

            foreach (var evidence in dataset.Identifications)
            {
                var sequence    = evidence.Peptide.GetIpSequence();
                var sequenceStr = GetSequenceStr(sequence);

                foreach (var pepEv in evidence.PepEvidence)
                {
                    if (pepEv.IsDecoy || pepEv.DbSeq.Accession.StartsWith("XXX"))
                    {
                        continue;
                    }

                    var prsm = new PrSm(sequenceReader)
                    {
                        Heavy          = false,
                        Scan           = evidence.ScanNum,
                        Charge         = evidence.Charge,
                        Sequence       = sequence,
                        SequenceText   = sequenceStr,
                        ProteinName    = pepEv.DbSeq.Accession,
                        ProteinDesc    = pepEv.DbSeq.ProteinDescription,
                        Score          = evidence.SpecEv,
                        UseGolfScoring = true,
                        QValue         = evidence.QValue,
                    };
                    prsmList.Add(prsm);
                }
            }

            return(prsmList);
        }
        /// <summary>
        /// Create Protein-Spectrum-Matches identification from a line of the results file.
        /// </summary>
        /// <param name="line">Single line of the results file.</param>
        /// <param name="headers">Headers of the TSV file.</param>
        /// <param name="modIgnoreList">Ignores modifications contained in this list.</param>
        /// <returns>List of Protein-Spectrum-Match identifications.</returns>
        private IEnumerable <PrSm> CreatePrSms(string line, IReadOnlyDictionary <string, int> headers, IEnumerable <string> modIgnoreList)
        {
            var expectedHeaders = new List <string>
            {
                "Score",
                "Protein",
                "Description",
                "Sequence",
                "Scan",
            };

            foreach (var header in expectedHeaders.Where(header => !headers.ContainsKey(header)))
            {
                throw new KeyNotFoundException(string.Format("Missing expected column header \"{0}\" in ID file.", header));
            }

            var parts      = line.Split('\t');
            var scoreLabel = "Score";

            var score = Convert.ToDouble(parts[headers[scoreLabel]]);

            var proteinNames = parts[headers["Protein"]].Split(';');
            var prsmList     = new List <PrSm> {
                Capacity = proteinNames.Length
            };

            if (modIgnoreList != null)
            {
                if (modIgnoreList.Select(mod => string.Format("{0} ", mod)).Any(searchMod => parts[headers["Modifications"]].Contains(searchMod)))
                {
                    return(null);
                }
            }

            var sequenceReader = new SequenceReader();

            foreach (var protein in proteinNames)
            {
                var prsm = new PrSm(sequenceReader)
                {
                    Heavy  = false,
                    Scan   = Convert.ToInt32(parts[headers["Scan"]]),
                    Charge = 1,
                    ////Sequence = sequenceData.Item1,
                    SequenceText = parts[headers["Sequence"]],
                    ProteinName  = protein,
                    ProteinDesc  = parts[headers["Description"]].Split(';').FirstOrDefault(),
                    Score        = Math.Round(score, 3),
                };
                prsmList.Add(prsm);
            }

            return(prsmList);
        }
        public async Task ExportAsync(PrSm id, string outputPath)
        {
            var plotModel = await GetPlotModelAsync(id);

            DynamicResolutionPngExporter.Export(
                plotModel,
                outputPath,
                1280,
                1024,
                OxyColors.White,
                dpi);
        }
예제 #5
0
 public void Export(PrSm id, string outputFilePath)
 {
     using (var writer = new StreamWriter(outputFilePath))
     {
         var matches = GetMappedPeaks(id);
         writer.WriteLine(GetHeaders());
         foreach (var match in matches)
         {
             writer.WriteLine(GetLine(match));
         }
     }
 }
        public void Export(PrSm id, string outputPath)
        {
            var plotModel = GetPlotModel(id);

            DynamicResolutionPngExporter.Export(
                plotModel,
                outputPath,
                1280,
                1024,
                OxyColors.White,
                dpi);
        }
예제 #7
0
        public async Task ExportAsync(PrSm id, string outputFilePath)
        {
            using (var writer = new StreamWriter(outputFilePath))
            {
                var matches = await GetMappedPeaksAsync(id);

                await writer.WriteLineAsync(GetHeaders());

                foreach (var match in matches)
                {
                    await writer.WriteLineAsync(GetLine(match));
                }
            }
        }
예제 #8
0
        public async Task <IEnumerable <PrSm> > ReadAsync(IEnumerable <string> modIgnoreList = null, IProgress <double> progress = null)
        {
            var oStartupOptions = new clsPHRPStartupOptions {
                LoadModsAndSeqInfo = true
            };
            var phrpReader = new clsPHRPReader(filePath, oStartupOptions);

            if (!string.IsNullOrEmpty(phrpReader.ErrorMessage))
            {
                throw new Exception(phrpReader.ErrorMessage);
            }

            var identifications = await Task.Run(
                () =>
            {
                var ids = new List <PrSm>();
                while (phrpReader.MoveNext())
                {
                    phrpReader.FinalizeCurrentPSM();
                    var psm      = phrpReader.CurrentPSM;
                    var proteins = psm.Proteins;

                    var parsedSequence = ParseSequence(psm.PeptideCleanSequence, psm.ModifiedResidues);
                    foreach (var protein in proteins)
                    {
                        var prsm = new PrSm
                        {
                            Heavy          = false,
                            ProteinName    = protein,
                            ProteinDesc    = string.Empty,
                            Charge         = psm.Charge,
                            Sequence       = parsedSequence,
                            Scan           = psm.ScanNumber,
                            Score          = Convert.ToDouble(psm.MSGFSpecProb),
                            UseGolfScoring = true,
                            QValue         = 0,
                        };

                        prsm.SetSequence(GetSequenceText(parsedSequence), parsedSequence);

                        ids.Add(prsm);
                    }
                }

                return(ids);
            });

            return(identifications);
        }
예제 #9
0
        /// <summary>
        /// Score a <see cref="PrSm" /> based on its sequence and MS/MS spectrum.
        /// </summary>
        /// <param name="prsm">The <see cref="PrSm" /> to score.</param>
        private void UpdatePrSmScore(PrSm prsm)
        {
            if (this.ScorerFactory == null)
            {
                return;
            }

            var ms2Spectrum = prsm.Ms2Spectrum;

            if (ms2Spectrum == null)
            {
                return;
            }

            var scorer = this.ScorerFactory.GetScorer(prsm.Ms2Spectrum);

            prsm.Score = IonUtils.ScoreSequence(scorer, prsm.Sequence);
        }
예제 #10
0
        private IEnumerable <Tuple <Peak, PeakDataPoint> > GetMappedPeaks(PrSm id)
        {
            var lcms         = id.LcMs;
            var fragSequence = id.GetFragmentationSequence();
            var fragments    = lcms.GetMsLevel(id.Scan) == 2 ?
                               fragSequence.GetFragmentLabels(ionTypes.Where(ionType => ionType.Charge <= id.Charge).ToList()) :
                               fragSequence.GetChargePrecursorLabels();
            var spectrum = lcms.GetSpectrum(id.Scan, true);

            // Get the fragment peaks
            var fragmentPeaks = fragments.SelectMany(fragment => fragment.GetPeaks(spectrum, false, false))
                                .OrderBy(peakDataPoint => peakDataPoint.X)
                                .ToArray();

            // Set the correct residue for the fragment peaks
            foreach (var peak in fragmentPeaks)
            {
                peak.Residue = GetResidue(id.Sequence, peak.Index, peak.IonType.IsPrefixIon);
            }

            return(spectrum.Peaks.Select(peak => GetMatch(peak, fragmentPeaks)));
        }
예제 #11
0
        /// <summary>
        /// Read a MZID results file asynchronously.
        /// </summary>
        /// <param name="modIgnoreList">Ignores modifications contained in this list.</param>
        /// <param name="progress">The progress reporter.</param>
        /// <returns>Identification tree of MZID identifications.</returns>
        public async Task <IEnumerable <PrSm> > ReadAsync(IEnumerable <string> modIgnoreList = null, IProgress <double> progress = null)
        {
            var dataset = await Task.Run(() => this.mzIdentMlReader.Read(this.filePath));

            var prsms          = new List <PrSm>();
            var sequenceReader = new SequenceReader();

            foreach (var evidence in dataset.Identifications)
            {
                var sequence    = evidence.Peptide.GetIpSequence();
                var sequenceStr = this.GetSequenceStr(sequence);

                foreach (var pepEv in evidence.PepEvidence)
                {
                    if (pepEv.IsDecoy || pepEv.DbSeq.Accession.StartsWith("XXX"))
                    {
                        continue;
                    }

                    var prsm = new PrSm(sequenceReader)
                    {
                        Heavy          = false,
                        Scan           = evidence.ScanNum,
                        Charge         = evidence.Charge,
                        Sequence       = sequence,
                        SequenceText   = sequenceStr,
                        ProteinName    = pepEv.DbSeq.Accession,
                        ProteinDesc    = pepEv.DbSeq.ProteinDescription,
                        Score          = evidence.SpecEv,
                        UseGolfScoring = true,
                        QValue         = evidence.QValue,
                    };
                    prsms.Add(prsm);
                }
            }

            return(prsms);
        }
예제 #12
0
        /// <summary>
        /// Highlight an identification on the feature map plot.
        /// </summary>
        /// <param name="prsm">Identification to highlight.</param>
        private void SetHighlight(PrSm prsm)
        {
            if (prsm == null)
            {
                return;
            }

            ////prsm.LcMs = this.lcms;
            var rt   = prsm.RetentionTime;
            var mass = prsm.Mass;

            if (this.highlight == null)
            {
                this.highlight = new RectangleAnnotation
                {
                    TextPosition    = new DataPoint(rt, mass),
                    Fill            = OxyColor.FromArgb(100, 255, 255, 0),
                    Stroke          = OxyColor.FromRgb(0, 255, 0),
                    StrokeThickness = 2,
                    MinimumX        = rt - ((this.xaxis.ActualMaximum - this.xaxis.ActualMinimum) * HighlightScale * 0.5),
                    MaximumX        = rt + ((this.xaxis.ActualMaximum - this.xaxis.ActualMinimum) * HighlightScale * 0.5),
                    MinimumY        = mass - ((this.yaxis.ActualMaximum - this.yaxis.ActualMinimum) * HighlightScale),
                    MaximumY        = mass + ((this.yaxis.ActualMaximum - this.yaxis.ActualMinimum) * HighlightScale),
                };

                this.FeatureMap.Annotations.Add(this.highlight);
            }
            else
            {
                this.highlight.TextPosition = new DataPoint(rt, mass);
                this.highlight.MinimumX     = rt - ((this.xaxis.ActualMaximum - this.xaxis.ActualMinimum) * HighlightScale * 0.5);
                this.highlight.MaximumX     = rt + ((this.xaxis.ActualMaximum - this.xaxis.ActualMinimum) * HighlightScale * 0.5);
                this.highlight.MinimumY     = mass - ((this.yaxis.ActualMaximum - this.yaxis.ActualMinimum) * HighlightScale);
                this.highlight.MaximumY     = mass + ((this.yaxis.ActualMaximum - this.yaxis.ActualMinimum) * HighlightScale);
            }
        }
예제 #13
0
        /// <summary>
        /// Initializes a new instance of the <see cref="DataSetViewModel"/> class.
        /// </summary>
        /// <param name="dialogService">A dialog service for opening dialogs from the view model</param>
        public DataSetViewModel(IMainDialogService dialogService)
        {
            this.dialogService      = dialogService;
            ReadyToClose            = false;
            IdFileOpen              = false;
            SelectedPrSm            = new PrSm();
            ScanViewModel           = new ScanViewModel(dialogService, new List <PrSm>());
            CreateSequenceViewModel = new CreateSequenceViewModel(dialogService)
            {
                SelectedDataSetViewModel = this
            };

            CreateSequenceViewModel.CreateAndAddPrSmCommand.Subscribe(
                _ => ScanViewModel.Data.Add(CreateSequenceViewModel.SelectedPrSm));

            // Remove filter by raw file name from ScanViewModel filters
            ScanViewModel.Filters.Remove(ScanViewModel.Filters.FirstOrDefault(f => f.Name == "Raw File Name"));

            // When a PrSm is selected from the ScanViewModel, update the SelectedPrSm for this data set
            ScanViewModel.WhenAnyValue(x => x.SelectedPrSm).Where(prsm => prsm != null).Subscribe(x => SelectedPrSm = x);

            // When the scan number in the selected prsm changes, the selected scan in the xic plots should update
            this.WhenAnyValue(x => x.SelectedPrSm)
            .Where(_ => SelectedPrSm != null && SpectrumViewModel != null && XicViewModel != null)
            .Subscribe(prsm =>
            {
                SpectrumViewModel.UpdateSpectra(prsm.Scan, SelectedPrSm.PrecursorMz);
                XicViewModel.SetSelectedScan(prsm.Scan);
                XicViewModel.ZoomToScan(prsm.Scan);
            });

            var prsmObservable = this.WhenAnyValue(x => x.SelectedPrSm).Where(prsm => prsm != null);

            prsmObservable
            .Select(prsm => prsm.GetFragmentationSequence()).Where(fragSeq => fragSeq != null)
            .Subscribe(fragSeq =>
            {
                SpectrumViewModel.FragmentationSequence = fragSeq;
                XicViewModel.FragmentationSequence      = fragSeq;
            });

            // When the prsm changes, update the Scan View Model.
            prsmObservable.Subscribe(prsm => ScanViewModel.SelectedPrSm = prsm);

            // When the prsm updates, update the prsm in the sequence creator
            prsmObservable.Subscribe(prsm => CreateSequenceViewModel.SelectedPrSm = prsm);

            // When the prsm updates, update the feature map
            prsmObservable.Where(_ => FeatureMapViewModel != null).Subscribe(prsm => FeatureMapViewModel.FeatureMapViewModel.SelectedPrSm = prsm);

            // When prsm updates, subscribe to scan updates
            prsmObservable.Subscribe(prsm =>
            {
                prsm.WhenAnyValue(x => x.Scan, x => x.PrecursorMz)
                .Where(x => x.Item1 > 0 && x.Item2 > 0 && SpectrumViewModel != null)
                .Subscribe(x => SpectrumViewModel.UpdateSpectra(x.Item1, x.Item2));
                prsm.WhenAnyValue(x => x.Scan).Where(scan => scan > 0 && XicViewModel != null)
                .Subscribe(scan => XicViewModel.SetSelectedScan(scan));
            });

            // When a new prsm is created by CreateSequenceViewModel, update SelectedPrSm
            CreateSequenceViewModel.WhenAnyValue(x => x.SelectedPrSm).Subscribe(prsm => SelectedPrSm = prsm);

            // When IDs are filtered in the ScanViewModel, update feature map with new IDs
            ScanViewModel.WhenAnyValue(x => x.FilteredData).Where(_ => FeatureMapViewModel != null).Subscribe(data => FeatureMapViewModel.UpdateIds(data));

            // Toggle instrument data when ShowInstrumentData setting is changed.
            IcParameters.Instance.WhenAnyValue(x => x.ShowInstrumentData).Select(async x => await ScanViewModel.ToggleShowInstrumentDataAsync(x, (PbfLcMsRun)LcMs)).Subscribe();

            // When product ion tolerance or ion correlation threshold change, update scorer factory
            IcParameters.Instance.WhenAnyValue(x => x.ProductIonTolerancePpm, x => x.IonCorrelationThreshold)
            .Subscribe(
                x =>
            {
                var scorer = new ScorerFactory(x.Item1, Constants.MinCharge, Constants.MaxCharge, x.Item2);
                CreateSequenceViewModel.ScorerFactory = scorer;
                ScanViewModel.ScorerFactory           = scorer;
            });

            // When an ID file has been opened, turn on the unidentified scan filter
            this.WhenAnyValue(x => x.IdFileOpen)
            .Where(idFileOpen => idFileOpen)
            .Select(_ => ScanViewModel.Filters.FirstOrDefault(f => f.Name == "Hide Unidentified Scans"))
            .Where(f => f != null)
            .Subscribe(f => f.Selected = true);

            // Start MsPf Search Command
            StartMsPfSearchCommand = ReactiveCommand.Create(StartMsPfSearchImplementation);

            // Close command verifies that the user wants to close the dataset, then sets ReadyToClose to true if they are
            CloseCommand = ReactiveCommand.Create(() =>
            {
                ReadyToClose =
                    dialogService.ConfirmationBox(
                        string.Format("Are you sure you would like to close {0}?", Title), string.Empty);
            });
        }
예제 #14
0
 private async Task <IEnumerable <Tuple <Peak, PeakDataPoint> > > GetMappedPeaksAsync(PrSm id)
 {
     return(await Task.Run(() => GetMappedPeaks(id)));
 }
예제 #15
0
        /// <summary>
        /// Create Protein-Spectrum-Matches identification from a line of the results file.
        /// </summary>
        /// <param name="line">Single line of the results file.</param>
        /// <param name="headers">Headers of the TSV file.</param>
        /// <param name="modIgnoreList">Ignores modifications contained in this list.</param>
        /// <returns>List of Protein-Spectrum-Match identifications.</returns>
        private IEnumerable <PrSm> CreatePrSms(string line, IReadOnlyDictionary <string, int> headers, IEnumerable <string> modIgnoreList = null)
        {
            var expectedHeaders = new List <string>
            {
                "Protein",
                "Peptide",
                "Charge",
                "QValue",
            };

            foreach (var header in expectedHeaders.Where(header => !headers.ContainsKey(header)))
            {
                throw new KeyNotFoundException(string.Format("Missing expected column header \"{0}\" in ID file.", header));
            }

            var parts = line.Split('\t');

            double score = 0;

            if (headers.TryGetValue("SpecEValue", out var scoreIndex))
            {
                score = Convert.ToDouble(parts[scoreIndex]);
            }
            else if (headers.TryGetValue("MSGFDB_SpecEValue", out scoreIndex))
            {
                score = Convert.ToDouble(parts[scoreIndex]);
            }

            var scan = 0;

            if (headers.TryGetValue("ScanNum", out var scanIndex))
            {
                scan = Convert.ToInt32(parts[scanIndex]);
            }
            else if (headers.TryGetValue("Scan", out scanIndex))
            {
                scan = Convert.ToInt32(parts[scanIndex]);
            }

            var proteinNames = parts[headers["Protein"]].Split(';');
            var prsms        = new List <PrSm> {
                Capacity = proteinNames.Length
            };

            var sequenceText = parts[headers["Peptide"]];

            if (modIgnoreList != null)
            {
                if (modIgnoreList.Any(sequenceText.Contains))
                {
                    return(null);
                }
            }

            var sequenceReader = new SequenceReader(filePath.Contains("_syn"));

            foreach (var protein in proteinNames)
            {
                var prsm = new PrSm(sequenceReader)
                {
                    Heavy  = false,
                    Scan   = scan,
                    Charge = Convert.ToInt32(parts[headers["Charge"]]),
                    ////Sequence = sequenceReader.Read(sequenceText, trim),
                    SequenceText   = sequenceText,
                    ProteinName    = protein,
                    ProteinDesc    = string.Empty,
                    Score          = score,
                    UseGolfScoring = true,
                    QValue         = Math.Round(Convert.ToDouble(parts[headers["QValue"]]), 4),
                };
                prsms.Add(prsm);
            }

            return(prsms);
        }
        private PlotModel GetPlotModel(PrSm id)
        {
            var lcms         = id.LcMs;
            var fragSequence = id.GetFragmentationSequence();
            var msLevel      = lcms.GetMsLevel(id.Scan);
            var fragments    = msLevel == 2 ?
                               fragSequence.GetFragmentLabels(ionTypes.Where(ionType => ionType.Charge <= id.Charge).ToList()) :
                               fragSequence.GetChargePrecursorLabels();
            var spectrum = lcms.GetSpectrum(id.Scan, true);

            // Set up plot
            var plotModel = new PlotModel
            {
                Title = msLevel == 2 ? string.Format("MS/MS Scan {0}", id.Scan) :
                        string.Format("MS Scan {0}", id.Scan),
                IsLegendVisible = false,
            };

            // Add axes
            var xaxis = new LinearAxis {
                Title = "M/Z", Position = AxisPosition.Bottom
            };
            var yaxis = new LinearAxis {
                Title = "Intensity", Position = AxisPosition.Left, Minimum = 0
            };

            plotModel.Axes.Add(xaxis);
            plotModel.Axes.Add(yaxis);

            // Add spectrum peaks
            var spectrumPeaks      = spectrum.Peaks.Select(peak => new PeakDataPoint(peak.Mz, peak.Intensity, 0.0, 0.0, string.Empty));
            var spectrumStemSeries = new StemSeries
            {
                ItemsSource     = spectrumPeaks,
                Color           = OxyColors.Black,
                StrokeThickness = 0.5,
            };

            plotModel.Series.Add(spectrumStemSeries);

            // Add ion highlights
            var colors = new IonColorDictionary(id.Charge);

            foreach (var fragment in fragments)
            {
                var points = fragment.GetPeaks(spectrum, false, false);
                if (points.Count == 0 || points[0].Error.Equals(double.NaN))
                {
                    continue;
                }

                var firstPoint = points[0];
                var color      = firstPoint.IonType != null?colors.GetColor(firstPoint.IonType.BaseIonType, firstPoint.IonType.Charge)
                                     : colors.GetColor(firstPoint.Index);

                var ionSeries = new PeakPointSeries
                {
                    Color           = color,
                    StrokeThickness = 1.5,
                    ItemsSource     = points,
                    Title           = points[0].Title,
                };

                // Create ion name annotation
                var annotation = new TextAnnotation
                {
                    Text            = points[0].Title,
                    TextColor       = color,
                    FontWeight      = FontWeights.Bold,
                    Layer           = AnnotationLayer.AboveSeries,
                    FontSize        = 12,
                    Background      = OxyColors.White,
                    Padding         = new OxyThickness(0.1),
                    TextPosition    = new DataPoint(points[0].X, points[0].Y),
                    StrokeThickness = 0
                };
                plotModel.Series.Add(ionSeries);
                plotModel.Annotations.Add(annotation);
            }

            return(plotModel);
        }
 private Task <PlotModel> GetPlotModelAsync(PrSm id)
 {
     return(Task.Run(() => GetPlotModel(id)));
 }
예제 #18
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ScanViewModel"/> class.
        /// </summary>
        /// <param name="dialogService">Dialog service for opening dialogs from the view model.</param>
        /// <param name="ids">The Protein-Spectrum-Match identifications to display.</param>
        public ScanViewModel(IMainDialogService dialogService, IEnumerable <PrSm> ids)
        {
            ClearFiltersCommand = ReactiveCommand.Create(ClearFilters);
            this.dialogService  = dialogService;

            FilteredData     = new PrSm[0];
            FilteredProteins = new ReactiveList <ProteinId>();

            Filters = new ReactiveList <IFilter> {
                ChangeTrackingEnabled = true
            };

            Data = new ReactiveList <PrSm> {
                ChangeTrackingEnabled = true
            };
            InitializeDefaultFilters();
            Data.AddRange(ids);

            IdTree = new IdentificationTree();

            // When a filter is selected/unselected, request a filter value if selected, then filter data
            Filters.ItemChanged.Where(x => x.PropertyName == "Selected")
            .Select(x => x.Sender)
            .Where(sender => !sender.Selected || sender.Name == "Hide Unidentified Scans" || this.dialogService.FilterBox(sender))
            .SelectMany(async _ => await FilterDataAsync(Data))
            .Subscribe(fd => FilteredData = fd);

            // Data changes when items are added or removed
            Data.CountChanged.Throttle(TimeSpan.FromMilliseconds(500), RxApp.TaskpoolScheduler)
            .SelectMany(async _ => await FilterDataAsync(Data))
            .Subscribe(fd => FilteredData = fd);

            // When data is filtered, group it by protein name
            this.WhenAnyValue(x => x.FilteredData).ObserveOn(RxApp.MainThreadScheduler)
            .Subscribe(async filteredData =>
            {
                IdTree.ClearIds();
                await IdTree.BuildIdTree(filteredData);
                FilteredProteins.Clear();
                foreach (var protein in IdTree.ProteinIds)
                {
                    FilteredProteins.Add(protein);
                }
            });

            // When data is filtered and a PRSM has not been selected yet, select the first PRSM
            this.WhenAnyValue(x => x.FilteredData)
            .Where(fd => fd.Length > 0)
            .Where(_ => SelectedPrSm == null)
            .Subscribe(fd => SelectedPrSm = fd[0]);

            // When a tree object is selected and it is a PRSM, set the selected PRSM
            this.WhenAnyValue(x => x.TreeViewSelectedItem)
            .Select(x => x as PrSm)
            .Where(p => p != null)
            .Subscribe(p => SelectedPrSm = p);

            // When a tree object is selected and it is an IIdData, set the selected PRSM
            this.WhenAnyValue(x => x.TreeViewSelectedItem)
            .Select(x => x as IIdData)
            .Where(p => p != null)
            .Subscribe(p => SelectedPrSm = p.GetHighestScoringPrSm());

            // When a PrSm's sequence changes, update its score.
            Data.ItemChanged.Where(x => x.PropertyName == "Sequence")
            .Select(x => x.Sender)
            .Where(sender => sender.Sequence.Count > 0)
            .Subscribe(UpdatePrSmScore);

            ExportSpectraCommand     = ReactiveCommand.CreateFromTask(ExportSpectraImplementation);
            ExportPeaksCommand       = ReactiveCommand.CreateFromTask(ExportPeaksImplementation);
            ExportProteinTreeCommand = ReactiveCommand.Create(ExportProteinTreeImplementation);

            ExportProteinTreeAsTsvCommand = ReactiveCommand.Create(ExportProteinTreeAsTsvImplementation);
        }
예제 #19
0
        /// <summary>
        /// Implementation of the CreatePRSM command.
        /// Creates a new protein-spectrum match for the selected sequence,
        /// charge, and scan number.
        /// </summary>
        private void CreatePrSmImplementation()
        {
            var      sequenceReader = new SequenceReader();
            Sequence sequence       = null;

            try
            {
                sequence = sequenceReader.Read(this.SequenceText);
                if (sequence == null)
                {
                    throw new FormatException("Invalid Sequence.");
                }
            }
            catch (FormatException e)
            {
                this.dialogService.MessageBox(e.Message);
                return;
            }
            finally
            {
                if (sequence == null)
                {
                    sequence = new Sequence(new List <AminoAcid>());
                }
            }

            if (sequence.Count > 0 && this.SelectedCharge == 0)
            {
                this.dialogService.MessageBox("Invalid Charge state.");
                return;
            }

            if (sequence.Count == 0 && this.SelectedScan < 0)
            {
                this.dialogService.MessageBox("Invalid scan number.");
                return;
            }

            ILcMsRun lcms = this.SelectedDataSetViewModel.LcMs;

            double score = -1.0;

            if (lcms != null && this.SelectedScan > 0 && this.ScorerFactory != null && sequence.Count > 0)
            {
                var spectrum = lcms.GetSpectrum(this.SelectedScan) as ProductSpectrum;
                if (spectrum != null)
                {
                    var scorer = this.ScorerFactory.GetScorer(spectrum);
                    score = IonUtils.ScoreSequence(scorer, sequence);
                }
            }

            string rawFileName = this.SelectedDataSetViewModel.Title;
            var    prsm        = new PrSm
            {
                Heavy        = false,
                RawFileName  = rawFileName,
                ProteinName  = string.Empty,
                ProteinDesc  = string.Empty,
                Scan         = Math.Min(Math.Max(this.SelectedScan, 0), lcms.MaxLcScan),
                LcMs         = lcms,
                Charge       = this.SelectedCharge,
                Sequence     = sequence,
                SequenceText = this.SequenceText,
                Score        = score,
            };

            this.SelectedPrSm = prsm;
        }
예제 #20
0
        /// <summary>
        /// Read a MTDB Creator results file asynchronously.
        /// </summary>
        /// <param name="modIgnoreList">Ignores modifications contained in this list.</param>
        /// <param name="progress">The progress reporter.</param>
        /// <returns>The Protein-Spectrum-Match identifications.</returns>
        public async Task <IEnumerable <PrSm> > ReadAsync(IEnumerable <string> modIgnoreList = null, IProgress <double> progress = null)
        {
            var prsms = new List <PrSm>();

            if (!File.Exists(filePath))
            {
                return(prsms);
            }

            var database = await Task.Run(() => MtdbCreator.LoadDB(filePath));

            foreach (var target in database.ConsensusTargets)
            {
                foreach (var id in target.Evidences)
                {
                    // Degan: attempting to make it recognize the proteins from .mtdb format
                    foreach (var prot in id.Proteins)
                    {
                        var strippedSequence = target.Sequence;
                        strippedSequence = strippedSequence.Remove(0, 2);
                        strippedSequence = strippedSequence.Remove(strippedSequence.Length - 2, 2);
                        var entry = new PrSm {
                            Sequence = new Sequence(strippedSequence, new AminoAcidSet())
                        };

                        var rawSequence = target.Sequence;
                        var offset      = target.Sequence.IndexOf('.');
                        var length      = target.Sequence.Length;

                        foreach (var ptm in id.Ptms)
                        {
                            var position = rawSequence.Length - (length - (ptm.Location + offset));
                            var symbol   = string.Empty;

                            // We only need to add the sign on positive values - the '-' is automatic on negative values
                            if (ptm.Mass >= 0)
                            {
                                symbol = "+";
                            }

                            rawSequence = rawSequence.Insert(position + 1, symbol + ptm.Mass);

                            var modComposition = Composition.ParseFromPlainString(ptm.Formula);
                            var mod            = IcParameters.Instance.RegisterModification(ptm.Name, modComposition);
                            entry.Sequence[ptm.Location - 1] = new ModifiedAminoAcid(entry.Sequence[ptm.Location - 1], mod);
                        }

                        // Degan: attempting to make it recognize the proteins from .mtdb format
                        entry.ProteinName = prot.ProteinName;

                        // Degan: choosing stripped sequence rather than the raw sequence to exclude prior and successive amino acid
                        entry.SequenceText = strippedSequence;
                        entry.Charge       = id.Charge;
                        entry.Scan         = id.Scan;
                        prsms.Add(entry);
                    }
                }
            }

            return(prsms);
        }
예제 #21
0
        /// <summary>
        /// Event handler for mouse click event to set SelectedDataPoint
        /// </summary>
        /// <param name="sender">The sender PlotView</param>
        /// <param name="args">The event arguments.</param>
        private void FeatureMapMouseDown(object sender, OxyMouseEventArgs args)
        {
            this.selectedFeaturePoint = null;
            this.selectedPrSmPoint    = null;
            var series = this.FeatureMap.GetSeriesFromPoint(args.Position, 10);

            if (series is LineSeries)
            { // Was a feature clicked?
                var result = series.GetNearestPoint(args.Position, false);
                if (result == null)
                {
                    return;
                }

                var featurePoint = result.Item as Feature.FeaturePoint;
                if (featurePoint != null)
                {
                    // See if there is a ms2 point closer than this feature point
                    PrSm closestPrSm = null;
                    if (this.showFoundIdMs2 || this.showFoundUnIdMs2)
                    {
                        var feature = featurePoint.Feature;
                        var prsms   = feature.AssociatedPrSms;
                        var minDist = result.Position.DistanceToSquared(args.Position);
                        foreach (var prsm in prsms)
                        {
                            if ((prsm.Sequence.Count == 0 && !this.showFoundUnIdMs2) ||
                                (prsm.Sequence.Count > 0 && !this.showFoundIdMs2))
                            {
                                continue;
                            }

                            var sp     = this.xaxis.Transform(prsm.RetentionTime, featurePoint.Mass, this.yaxis);
                            var distSq = sp.DistanceToSquared(args.Position);
                            if (closestPrSm == null || distSq < minDist)
                            {
                                closestPrSm = prsm;
                                minDist     = distSq;
                            }
                        }
                    }

                    if (closestPrSm != null)
                    {
                        this.selectedPrSmPoint = closestPrSm;
                    }

                    this.selectedFeaturePoint = featurePoint;
                }
            }
            else if (series is ScatterSeries)
            { // Was a ms2 cross clicked?
                var result = series.GetNearestPoint(args.Position, false);
                if (result == null)
                {
                    return;
                }

                this.selectedPrSmPoint = result.Item as PrSm;
            }
        }