/// <summary> /// Set the LCMSRun for all data. /// </summary> /// <param name="lcms">LCMSRun to set.</param> /// <param name="dataSetName">Name of the data this for the LCMSRun.</param> public void SetLcmsRun(ILcMsRun lcms, string dataSetName) { foreach (var chargeState in this.ChargeStates.Values) { chargeState.SetLcmsRun(lcms, dataSetName); } }
/// <summary> /// Constructor /// </summary> /// <param name="run">LcMsRun (for determining minimum and maximum elution time</param> /// <param name="features">List of features</param> /// <param name="title">Plot title</param> /// <param name="minMass">Minimum mass</param> /// <param name="maxMass">Maximum mass</param> public LcMsFeatureMap(ILcMsRun run, IList <LcMsFeature> features, string title, double minMass, double maxMass) : this(features, title, minMass, maxMass, Math.Max(run.GetElutionTime(run.MinLcScan) - 5, 0), run.GetElutionTime(run.MaxLcScan) + 5) { }
/// <summary> /// Set the LCMSRun for all data. /// </summary> /// <param name="lcms">LCMSRun to set.</param> /// <param name="dataSetName">Name of the data this for the LCMSRun.</param> public void SetLcmsRun(ILcMsRun lcms, string dataSetName) { foreach (var proteoform in Proteoforms.Values) { proteoform.SetLcmsRun(lcms, dataSetName); } }
public ScanBasedTagSearchEngine( ILcMsRun run, ISequenceTagFinder seqTagFinder, LcMsPeakMatrix featureFinder, FastaDatabase fastaDb, Tolerance tolerance, AminoAcidSet aaSet, CompositeScorerFactory ms2ScorerFactory = null, int minMatchedTagLength = DefaultMinMatchedTagLength, double maxSequenceMass = 50000.0, int minProductIonCharge = 1, int maxProductIonCharge = 20) { _run = run; _featureFinder = featureFinder; _searchableDb = new SearchableDatabase(fastaDb); _tolerance = tolerance; _aaSet = aaSet; _minMatchedTagLength = minMatchedTagLength; _maxSequenceMass = maxSequenceMass; _minProductIonCharge = minProductIonCharge; _maxProductIonCharge = maxProductIonCharge; MinScan = int.MinValue; MaxScan = int.MaxValue; _ms2ScorerFactory = ms2ScorerFactory; _seqTagFinder = seqTagFinder; }
/// <summary> /// Set the LCMSRun for all data in this IDTree. /// </summary> /// <param name="lcms">LCMSRun to set.</param> /// <param name="dataSetName">Name of the data this for the LCMSRun.</param> public void SetLcmsRun(ILcMsRun lcms, string dataSetName) { foreach (var protein in this.Proteins.Values) { protein.SetLcmsRun(lcms, dataSetName); } }
/// <summary> /// Set the LCMSRun for all data. /// </summary> /// <param name="lcms">LCMSRun to set.</param> /// <param name="dataSetName">Name of the data this for the LCMSRun.</param> public void SetLcmsRun(ILcMsRun lcms, string dataSetName) { foreach (var prsm in PrSms.Values) { prsm.RawFileName = dataSetName; prsm.LcMs = lcms; } }
public ProductScorerBasedOnDeconvolutedSpectra( ILcMsRun run, int minProductCharge = 1, int maxProductCharge = 20, double productTolerancePpm = 10, int isotopeOffsetTolerance = 2, double filteringWindowSize = 1.1 ) : this(run, minProductCharge, maxProductCharge, new Tolerance(productTolerancePpm), isotopeOffsetTolerance, filteringWindowSize) { }
/// <summary> /// Initializes a new instance of the <see cref="FragmentationSequence"/> class. /// </summary> /// <param name="sequence">The underlying sequence.</param> /// <param name="charge">Charge of sequence.</param> /// <param name="lcms">The LCMSRun for the data set.</param> /// <param name="activationMethod">The Activation Method.</param> public FragmentationSequence(Sequence sequence, int charge, ILcMsRun lcms, ActivationMethod activationMethod) { cacheLock = new object(); fragmentCache = new MemoizingMRUCache <Tuple <Composition, IonType>, LabeledIonViewModel>(GetLabeledIonViewModel, 1000); Sequence = sequence; Charge = charge; LcMsRun = lcms; ActivationMethod = activationMethod; }
public void BuildScanTimes(ILcMsRun lcms) { this.ScanTimes = new Dictionary <int, double>(); var ms1Scans = lcms.GetScanNumbers(1); foreach (var scan in ms1Scans) { this.ScanTimes.Add(scan, lcms.GetElutionTime(scan)); } }
public CompositeScorerFactory( ILcMsRun run, IMassBinning comparer, AminoAcidSet aaSet, int minProductCharge = 1, int maxProductCharge = 20, double productTolerancePpm = 10, int isotopeOffsetTolerance = 2, double filteringWindowSize = 1.1 ) : this(run, comparer, aaSet, minProductCharge, maxProductCharge, new Tolerance(productTolerancePpm), isotopeOffsetTolerance, filteringWindowSize) { }
public ProductScorerBasedOnDeconvolutedSpectra( ILcMsRun run, int minProductCharge, int maxProductCharge, Tolerance productTolerance, int isotopeOffsetTolerance = 2, double filteringWindowSize = 1.1) { _run = run; _minProductCharge = minProductCharge; _maxProductCharge = maxProductCharge; _productTolerance = productTolerance; FilteringWindowSize = filteringWindowSize; IsotopeOffsetTolerance = isotopeOffsetTolerance; _ms2Scorer = new Dictionary<int, IScorer>(); }
/// <summary> /// Initializes a new instance of the <see cref="LabeledIonViewModel"/> class. /// </summary> /// <param name="composition">The empirical formula for this ion.</param> /// <param name="ionType">The fragment IonType for this ion.</param> /// <param name="isFragmentIon">A value indicating whether this ion is a fragment ion.</param> /// <param name="lcms">The LCMSRun for the data set that the ion is part of.</param> /// <param name="precursorIon">The precursor ion if this is a fragment ion.</param> /// <param name="isChargeState"> /// A value indicating whether this ion is a neighboring charge state to another /// precursor ion. /// </param> /// <param name="index">The index of this ion.</param> public LabeledIonViewModel(Composition composition, IonType ionType, bool isFragmentIon, ILcMsRun lcms, Ion precursorIon = null, bool isChargeState = false, int index = 0) { Composition = composition; PrecursorIon = precursorIon; Index = index; IonType = ionType; IsFragmentIon = isFragmentIon; IsChargeState = isChargeState; selected = true; xicCacheLock = new object(); peakCacheLock = new object(); peakCache = new MemoizingMRUCache <Tuple <Spectrum, bool>, IList <PeakDataPoint> >(GetPeakDataPoints, 5); xicCache = new MemoizingMRUCache <int, IList <XicDataPoint> >(GetXic, 10); Lcms = lcms; }
public ProductScorerBasedOnDeconvolutedSpectra( ILcMsRun run, int minProductCharge, int maxProductCharge, Tolerance productTolerance, int isotopeOffsetTolerance = 2, double filteringWindowSize = 1.1) { _run = run; _minProductCharge = minProductCharge; _maxProductCharge = maxProductCharge; _productTolerance = productTolerance; FilteringWindowSize = filteringWindowSize; IsotopeOffsetTolerance = isotopeOffsetTolerance; _ms2Scorer = new Dictionary <int, IScorer>(); }
/// <summary> /// Initializes a new instance of the <see cref="PrSm"/> class. /// </summary> /// <param name="sequenceReader"> /// Sequence reader for parsing sequences for the dataset this PRSM belongs to. /// </param> public PrSm(ISequenceReader sequenceReader = null) { this.sequenceReader = sequenceReader ?? new SequenceReader(); this.RawFileName = string.Empty; this.SequenceText = string.Empty; this.Sequence = new Sequence(new List <AminoAcid>()); this.ProteinName = string.Empty; this.ProteinDesc = string.Empty; this.UseGolfScoring = false; this.Heavy = false; this.lcms = null; this.scan = 0; this.Mass = double.NaN; this.PrecursorMz = double.NaN; this.QValue = -1.0; this.charge = 1; }
/// <summary> /// Initializes a new instance of the <see cref="PrSm"/> class. /// </summary> /// <param name="sequenceReader"> /// Sequence reader for parsing sequences for the dataset this PRSM belongs to. /// </param> public PrSm(ISequenceReader sequenceReader) { this.sequenceReader = sequenceReader ?? new SequenceReader(); RawFileName = string.Empty; SequenceText = string.Empty; Sequence = new Sequence(new List <AminoAcid>()); ProteinName = string.Empty; ProteinDesc = string.Empty; UseGolfScoring = false; Heavy = false; lcms = null; scan = 0; Mass = double.NaN; PrecursorMz = double.NaN; QValue = -1.0; charge = 1; }
public CompositeScorerFactory( ILcMsRun run, IMassBinning comparer, AminoAcidSet aaSet, int minProductCharge, int maxProductCharge, Tolerance productTolerance, int isotopeOffsetTolerance = 2, double filteringWindowSize = 1.1) { _run = run; _minProductCharge = minProductCharge; _maxProductCharge = maxProductCharge; _productTolerance = productTolerance; FilteringWindowSize = filteringWindowSize; IsotopeOffsetTolerance = isotopeOffsetTolerance; _ms2Scorer = new Dictionary<int, IScorer>(); _comparer = comparer; _scoringGraphFactory = new ProteinScoringGraphFactory(comparer, aaSet); }
public CompositeScorerFactory( ILcMsRun run, IMassBinning comparer, AminoAcidSet aaSet, int minProductCharge, int maxProductCharge, Tolerance productTolerance, int isotopeOffsetTolerance = 2, double filteringWindowSize = 1.1) { _run = run; _minProductCharge = minProductCharge; _maxProductCharge = maxProductCharge; _productTolerance = productTolerance; FilteringWindowSize = filteringWindowSize; IsotopeOffsetTolerance = isotopeOffsetTolerance; _ms2Scorer = new Dictionary <int, IScorer>(); _comparer = comparer; _scoringGraphFactory = new ProteinScoringGraphFactory(comparer, aaSet); }
/// <summary> /// Initializes a new instance of the <see cref="XicViewModel"/> class. /// </summary> /// <param name="dialogService">A dialog service for opening dialogs from the view model</param> /// <param name="lcms">the LCMSRun representing the raw file for this dataset.</param> public XicViewModel(IMainDialogService dialogService, ILcMsRun lcms) { this.dialogService = dialogService; this.lcms = lcms; this.fragmentXAxis = new LinearAxis { StringFormat = "0.###", Position = AxisPosition.Bottom, Title = "Retention Time", AbsoluteMinimum = lcms.MinLcScan, AbsoluteMaximum = lcms.MaxLcScan + 1 }; this.fragmentXAxis.AxisChanged += this.XAxisChanged; this.FragmentPlotViewModel = new XicPlotViewModel( this.dialogService, new FragmentationSequenceViewModel { AddPrecursorIons = false }, lcms, "Fragment XIC", this.fragmentXAxis, false); this.heavyFragmentXAxis = new LinearAxis { StringFormat = "0.###", Position = AxisPosition.Bottom, Title = "Retention Time", AbsoluteMinimum = lcms.MinLcScan, AbsoluteMaximum = lcms.MaxLcScan + 1 }; this.heavyFragmentXAxis.AxisChanged += this.XAxisChanged; this.HeavyFragmentPlotViewModel = new XicPlotViewModel( this.dialogService, new FragmentationSequenceViewModel { AddPrecursorIons = false }, lcms, "Heavy Fragment XIC", this.heavyFragmentXAxis, false, AxisPosition.Right); this.precursorXAxis = new LinearAxis { StringFormat = "0.###", Position = AxisPosition.Bottom, Title = "Retention Time", AbsoluteMinimum = lcms.MinLcScan, AbsoluteMaximum = lcms.MaxLcScan + 1 }; this.precursorXAxis.AxisChanged += this.XAxisChanged; this.PrecursorPlotViewModel = new XicPlotViewModel(this.dialogService, new PrecursorSequenceIonViewModel(), lcms, "Precursor XIC", this.precursorXAxis) { IsPlotUpdating = true, }; this.heavyPrecursorXAxis = new LinearAxis { StringFormat = "0.###", Position = AxisPosition.Bottom, Title = "Retention Time", AbsoluteMinimum = lcms.MinLcScan, AbsoluteMaximum = lcms.MaxLcScan + 1 }; this.heavyPrecursorXAxis.AxisChanged += this.XAxisChanged; this.HeavyPrecursorPlotViewModel = new XicPlotViewModel( this.dialogService, new PrecursorSequenceIonViewModel(), lcms, "Heavy Precursor XIC", this.heavyPrecursorXAxis, vertAxes: AxisPosition.Right); this.showHeavy = false; this.showFragmentXic = false; var openHeavyModificationsCommand = ReactiveCommand.Create(); openHeavyModificationsCommand.Subscribe(_ => this.OpenHeavyModificationsImplentation()); this.OpenHeavyModificationsCommand = openHeavyModificationsCommand; this.PrecursorPlotViewModel.FragmentationSequenceViewModel.HeavyModifications = IcParameters.Instance.LightModifications.ToArray(); this.FragmentPlotViewModel.FragmentationSequenceViewModel.HeavyModifications = IcParameters.Instance.LightModifications.ToArray(); this.HeavyPrecursorPlotViewModel.FragmentationSequenceViewModel.HeavyModifications = IcParameters.Instance.HeavyModifications.ToArray(); this.HeavyFragmentPlotViewModel.FragmentationSequenceViewModel.HeavyModifications = IcParameters.Instance.HeavyModifications.ToArray(); this.linkedAxes = new Dictionary <LinearAxis, List <LinearAxis> > { { this.precursorXAxis, new List <LinearAxis>() }, { this.fragmentXAxis, new List <LinearAxis>() }, { this.heavyPrecursorXAxis, new List <LinearAxis>() }, { this.heavyFragmentXAxis, new List <LinearAxis>() } }; this.plotLinkageTracker = new HashSet <Tuple <LinearAxis, LinearAxis> >(); this.TogglePlotLinks(this.fragmentXAxis, this.heavyFragmentXAxis); this.TogglePlotLinks(this.precursorXAxis, this.heavyPrecursorXAxis); this.TogglePlotLinks(this.precursorXAxis, this.fragmentXAxis); this.TogglePlotLinks(this.heavyPrecursorXAxis, this.heavyFragmentXAxis); // Update area ratios when the area of any of the plots changes this.WhenAny(x => x.FragmentPlotViewModel.Area, x => x.HeavyFragmentPlotViewModel.Area, (x, y) => x.Value / y.Value) .Select(this.FormatRatio) .ToProperty(this, x => x.FragmentAreaRatioLabel, out this.fragmentAreaRatioLabel); this.WhenAny(x => x.PrecursorPlotViewModel.Area, x => x.HeavyPrecursorPlotViewModel.Area, (x, y) => x.Value / y.Value) .Select(this.FormatRatio) .ToProperty(this, x => x.PrecursorAreaRatioLabel, out this.precursorAreaRatioLabel); this.WhenAnyValue(x => x.ShowFragmentXic, x => x.ShowHeavy) .Subscribe(x => { this.FragmentPlotViewModel.IsPlotUpdating = x.Item1; this.HeavyFragmentPlotViewModel.IsPlotUpdating = x.Item1 && x.Item2; this.HeavyPrecursorPlotViewModel.IsPlotUpdating = x.Item2; }); this.WhenAnyValue(x => x.FragmentationSequence) .Where(fragSeq => fragSeq != null) .Subscribe(fragSeq => { this.FragmentPlotViewModel.FragmentationSequenceViewModel.FragmentationSequence = fragSeq; this.HeavyFragmentPlotViewModel.FragmentationSequenceViewModel.FragmentationSequence = fragSeq; this.PrecursorPlotViewModel.FragmentationSequenceViewModel.FragmentationSequence = fragSeq; this.HeavyPrecursorPlotViewModel.FragmentationSequenceViewModel.FragmentationSequence = fragSeq; }); this.PrecursorToFragmentLinkLabel = "L"; this.LightToHeavyLinkLabel = "L"; this.LinkLightToHeavyCommand = ReactiveCommand.Create(); this.LinkLightToHeavyCommand.Subscribe( _ => { this.TogglePlotLinks(this.fragmentXAxis, this.heavyFragmentXAxis); this.TogglePlotLinks(this.precursorXAxis, this.heavyPrecursorXAxis); this.LightToHeavyLinkLabel = this.LightToHeavyLinkLabel == "L" ? "U" : "L"; }); this.LinkPrecursorToFragmentCommand = ReactiveCommand.Create(); this.LinkPrecursorToFragmentCommand.Subscribe( _ => { this.TogglePlotLinks(this.precursorXAxis, this.fragmentXAxis); this.TogglePlotLinks(this.heavyPrecursorXAxis, this.heavyFragmentXAxis); this.PrecursorToFragmentLinkLabel = this.PrecursorToFragmentLinkLabel == "L" ? "U" : "L"; }); }
/// <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; }
/// <summary> /// Initializes a new instance of the <see cref="SpectrumViewModel"/> class. /// </summary> /// <param name="dialogService">Dialog service for opening dialogs from view model.</param> /// <param name="lcms">LCMSRun for the data set that the spectrum plots are part of.</param> public SpectrumViewModel(IMainDialogService dialogService, ILcMsRun lcms) { this.lcms = lcms; Ms2SpectrumViewModel = new SpectrumPlotViewModel(dialogService, new FragmentationSequenceViewModel(), 1.05); PrevMs1SpectrumViewModel = new SpectrumPlotViewModel( dialogService, new PrecursorSequenceIonViewModel { PrecursorViewMode = PrecursorViewMode.Charges }, 1.25, false); NextMs1SpectrumViewModel = new SpectrumPlotViewModel( dialogService, new PrecursorSequenceIonViewModel { PrecursorViewMode = PrecursorViewMode.Charges }, 1.25, false); // When prev ms1 spectrum plot is zoomed/panned, next ms1 spectrum plot should zoom/pan isAxisInternalChange = false; PrevMs1SpectrumViewModel.XAxis.AxisChanged += (o, e) => { if (isAxisInternalChange) { return; } isAxisInternalChange = true; NextMs1SpectrumViewModel.XAxis.Zoom(PrevMs1SpectrumViewModel.XAxis.ActualMinimum, PrevMs1SpectrumViewModel.XAxis.ActualMaximum); isAxisInternalChange = false; }; // When next ms1 spectrum plot is zoomed/panned, prev ms1 spectrum plot should zoom/pan NextMs1SpectrumViewModel.XAxis.AxisChanged += (o, e) => { if (isAxisInternalChange) { return; } isAxisInternalChange = true; PrevMs1SpectrumViewModel.XAxis.Zoom(NextMs1SpectrumViewModel.XAxis.ActualMinimum, NextMs1SpectrumViewModel.XAxis.ActualMaximum); isAxisInternalChange = false; }; this.WhenAnyValue(x => x.FragmentationSequence) .Where(fragSeq => fragSeq != null) .Subscribe(fragSeq => { Ms2SpectrumViewModel.FragmentationSequenceViewModel.FragmentationSequence = fragSeq; PrevMs1SpectrumViewModel.FragmentationSequenceViewModel.FragmentationSequence = fragSeq; NextMs1SpectrumViewModel.FragmentationSequenceViewModel.FragmentationSequence = fragSeq; }); // By default, MS2 Spectrum is shown in the primary view PrimarySpectrumViewModel = Ms2SpectrumViewModel; Secondary1ViewModel = PrevMs1SpectrumViewModel; Secondary2ViewModel = NextMs1SpectrumViewModel; // Wire commands to swap the spectrum that is shown in the primary view SwapSecondary1Command = ReactiveCommand.Create(SwapSecondary1); SwapSecondary2Command = ReactiveCommand.Create(SwapSecondary2); }
/// <summary> /// Initializes a new instance of the <see cref="IonListViewModel"/> class. /// </summary> /// <param name="lcms">The LCMSRun for the data set.</param> public IonListViewModel(ILcMsRun lcms) { prefixCompositionCache = new MemoizingMRUCache <Sequence, Composition[]>(GetPrefixCompositions, 20); suffixCompositionCache = new MemoizingMRUCache <Sequence, Composition[]>(GetSuffixCompositions, 20); this.lcms = lcms; fragmentCache = new MemoizingMRUCache <Tuple <Composition, IonType>, LabeledIonViewModel>(GetLabeledIonViewModel, 1000); cacheLock = new object(); IonTypes = new ReactiveList <IonType>(); ShowHeavy = false; FragmentLabels = new ReactiveList <LabeledIonViewModel>(); HeavyFragmentLabels = new ReactiveList <LabeledIonViewModel>(); PrecursorLabels = new ReactiveList <LabeledIonViewModel>(); HeavyPrecursorLabels = new ReactiveList <LabeledIonViewModel>(); ChargePrecursorLabels = new ReactiveList <LabeledIonViewModel>(); IsotopePrecursorLabels = new ReactiveList <LabeledIonViewModel>(); var precursorObservable = this.WhenAnyValue(x => x.SelectedPrSm, x => x.ShowHeavy).Where(x => x.Item1 != null); precursorObservable.Select(x => x.Item2 ? IcParameters.Instance.LightModifications : null) .SelectMany(async mods => await GenerateChargeLabelsAsync(mods)) .Subscribe(labels => ChargePrecursorLabels = labels); precursorObservable.Select(x => x.Item2 ? IcParameters.Instance.LightModifications : null) .SelectMany(async mods => await GenerateIsotopeLabelsAsync(mods)) .Subscribe(labels => { IsotopePrecursorLabels.ChangeTrackingEnabled = false; IsotopePrecursorLabels = labels; }); precursorObservable.Where(x => x.Item2) .SelectMany(async x => PrecursorViewMode == PrecursorViewMode.Isotopes ? await GenerateIsotopeLabelsAsync(IcParameters.Instance.HeavyModifications) : await GenerateChargeLabelsAsync(IcParameters.Instance.HeavyModifications)) .Subscribe(labels => { HeavyPrecursorLabels.ChangeTrackingEnabled = false; HeavyPrecursorLabels = labels; }); IcParameters.Instance.WhenAnyValue(x => x.PrecursorRelativeIntensityThreshold, x => x.LightModifications) .Where(_ => SelectedPrSm != null).Select(x => ShowHeavy ? x.Item2 : null) .SelectMany(async mods => await GenerateChargeLabelsAsync(mods)) .Subscribe(labels => { ChargePrecursorLabels.ChangeTrackingEnabled = false; ChargePrecursorLabels = labels; }); IcParameters.Instance.WhenAnyValue(x => x.PrecursorRelativeIntensityThreshold, x => x.LightModifications) .Where(_ => SelectedPrSm != null).Select(x => ShowHeavy ? x.Item2 : null) .SelectMany(async mods => await GenerateIsotopeLabelsAsync(mods)) .Subscribe(labels => { IsotopePrecursorLabels.ChangeTrackingEnabled = false; IsotopePrecursorLabels = labels; }); IcParameters.Instance.WhenAnyValue(x => x.PrecursorRelativeIntensityThreshold, x => x.HeavyModifications) .Where(_ => SelectedPrSm != null && ShowHeavy) .SelectMany(async x => PrecursorViewMode == PrecursorViewMode.Isotopes ? await GenerateIsotopeLabelsAsync(x.Item2) : await GenerateChargeLabelsAsync(x.Item2)) .Subscribe(labels => { HeavyPrecursorLabels.ChangeTrackingEnabled = false; HeavyPrecursorLabels = labels; }); this.WhenAnyValue(x => x.IsotopePrecursorLabels, x => x.ChargePrecursorLabels, x => x.PrecursorViewMode) .Select(x => x.Item3 == PrecursorViewMode.Isotopes ? x.Item1 : x.Item2) .Subscribe(labels => PrecursorLabels = labels); var fragmentObservable = this.WhenAnyValue(x => x.SelectedPrSm, x => x.IonTypes, x => x.ShowHeavy) .Where(x => x.Item1 != null) .Throttle(TimeSpan.FromMilliseconds(50), RxApp.TaskpoolScheduler); fragmentObservable.Select(x => x.Item3 ? IcParameters.Instance.LightModifications : null) .SelectMany(async mods => await GenerateFragmentLabelsAsync(mods)) .Subscribe(labels => FragmentLabels = labels); fragmentObservable.Where(x => x.Item3) .SelectMany(async mods => await GenerateFragmentLabelsAsync(IcParameters.Instance.HeavyModifications)) .Subscribe(labels => { HeavyFragmentLabels.ChangeTrackingEnabled = false; HeavyFragmentLabels = labels; }); IcParameters.Instance.WhenAnyValue(x => x.LightModifications) .Where(_ => SelectedPrSm != null).Select(mods => ShowHeavy ? mods : null) .SelectMany(async mods => await GenerateFragmentLabelsAsync(mods)) .Subscribe(labels => FragmentLabels = labels); IcParameters.Instance.WhenAnyValue(x => x.HeavyModifications) .Where(_ => SelectedPrSm != null && ShowHeavy) .SelectMany(async mods => await GenerateFragmentLabelsAsync(mods)) .Subscribe(labels => { HeavyFragmentLabels.ChangeTrackingEnabled = false; HeavyFragmentLabels = labels; }); EnableFragmentRowVirtualization = true; EnablePrecursorRowVirtualization = false; }
/// <summary> /// Initializes a new instance of the <see cref="XicPlotViewModel"/> class. /// </summary> /// <param name="dialogService">Dialog service </param> /// <param name="fragSeqVm">The view model for the fragmentation sequence (fragment ion generator)</param> /// <param name="lcms">LCMS run data set for this XIC plot. </param> /// <param name="title">Title of XIC plot </param> /// <param name="xaxis">XAxis for XIC plot. </param> /// <param name="showLegend">Should a legend be shown on the plot by default? </param> public XicPlotViewModel(IDialogService dialogService, IFragmentationSequenceViewModel fragSeqVm, ILcMsRun lcms, string title, LinearAxis xaxis, bool showLegend = true, AxisPosition vertAxes = AxisPosition.Left) { this.dialogService = dialogService; this.FragmentationSequenceViewModel = fragSeqVm; this.lcms = lcms; this.showLegend = showLegend; this.xaxis = xaxis; this.pointsToSmooth = IcParameters.Instance.PointsToSmooth; this.PlotTitle = title; this.PlotModel = new SelectablePlotModel(xaxis, 1.05) { YAxis = { Title = "Intensity", StringFormat = "0e0", Position = vertAxes } }; this.ions = new LabeledIonViewModel[0]; var retentionTimeSelectedCommand = ReactiveCommand.Create(); retentionTimeSelectedCommand .Select(_ => this.PlotModel.SelectedDataPoint as XicDataPoint) .Where(dp => dp != null) .Subscribe(dp => this.SelectedScan = dp.ScanNum); this.RetentionTimeSelectedCommand = retentionTimeSelectedCommand; var saveAsImageCommand = ReactiveCommand.Create(); saveAsImageCommand.Subscribe(_ => this.SaveAsImage()); this.SaveAsImageCommand = saveAsImageCommand; // When ShowLegend is updated, IsLegendVisible on the plot should be updated this.WhenAnyValue(x => x.ShowLegend).Subscribe(v => { this.PlotModel.IsLegendVisible = v; this.PlotModel.InvalidatePlot(true); }); // When area updates, plot title should update this.WhenAnyValue(x => x.Area).Subscribe(area => { var areaStr = string.Format(CultureInfo.InvariantCulture, "{0:0.##E0}", area); this.PlotTitle = string.Format("{0} (Area: {1})", title, areaStr); }); // Update area when x Axis is zoomed/panned this.xaxis.AxisChanged += async(o, e) => { this.Area = await this.GetCurrentAreaAsync(); }; // Update point marker when selected scan changes this.WhenAnyValue(x => x.SelectedScan, x => x.IsPlotUpdating) .Where(x => x.Item2) .Throttle(TimeSpan.FromMilliseconds(50), RxApp.TaskpoolScheduler) .Subscribe(x => this.PlotModel.SetPrimaryPointMarker(this.lcms.GetElutionTime(x.Item1))); // When point markers are toggled, change the marker type on each series this.WhenAnyValue(x => x.ShowPointMarkers) .Select(showPointMarkers => showPointMarkers ? MarkerType.Circle : MarkerType.None) .Subscribe( markerType => { foreach (var lineSeries in this.PlotModel.Series.OfType <LineSeries>()) { lineSeries.MarkerType = markerType; } this.PlotModel.InvalidatePlot(true); }); this.WhenAnyValue( x => x.FragmentationSequenceViewModel.LabeledIonViewModels, x => x.PointsToSmooth, x => x.IsPlotUpdating) .Where(x => x.Item3 && x.Item1 != null) .SelectMany(async x => await this.GetXicDataPointsAsync(x.Item1, this.PointsToSmooth)) .Subscribe(xicPoints => { this.ions = this.FragmentationSequenceViewModel.LabeledIonViewModels; this.UpdatePlotModel(xicPoints); }); // Update ions when relative intensity threshold changes. IcParameters.Instance.WhenAnyValue(x => x.PrecursorRelativeIntensityThreshold).Subscribe(precRelInt => { var precFragVm = this.FragmentationSequenceViewModel as PrecursorSequenceIonViewModel; if (precFragVm != null) { precFragVm.RelativeIntensityThreshold = precRelInt; } }); // Update plot when settings change IcParameters.Instance.WhenAnyValue(x => x.ProductIonTolerancePpm) .Where(_ => this.ions != null) .Throttle(TimeSpan.FromMilliseconds(250), RxApp.TaskpoolScheduler) .SelectMany(async x => await this.GetXicDataPointsAsync(this.ions, this.PointsToSmooth, false)) .Subscribe(this.UpdatePlotModel); }