/// <summary>
        /// Initializes a new instance of the <see cref="PrecursorSequenceIonViewModel"/> class.
        /// </summary>
        public PrecursorSequenceIonViewModel()
        {
            FragmentationSequence = new FragmentationSequence(
                new Sequence(new List <AminoAcid>()),
                1,
                null,
                ActivationMethod.HCD);
            HeavyModifications   = new SearchModification[0];
            PrecursorViewMode    = PrecursorViewMode.Isotopes;
            LabeledIonViewModels = new LabeledIonViewModel[0];

            this.WhenAnyValue(x => x.ChargeViewMode).Subscribe(chargeViewMode => IsotopeViewMode  = !chargeViewMode);
            this.WhenAnyValue(x => x.IsotopeViewMode).Subscribe(isotopeViewMode => ChargeViewMode = !isotopeViewMode);
            this.WhenAnyValue(x => x.IsotopeViewMode).Subscribe(isotopeViewMode =>
                                                                PrecursorViewMode = isotopeViewMode ? PrecursorViewMode.Isotopes : PrecursorViewMode.Charges);
            this.WhenAnyValue(x => x.PrecursorViewMode).Subscribe(
                viewMode =>
            {
                IsotopeViewMode = viewMode == PrecursorViewMode.Isotopes;
                ChargeViewMode  = viewMode == PrecursorViewMode.Charges;
            });

            this.WhenAnyValue(x => x.PrecursorViewMode, x => x.RelativeIntensityThreshold, x => x.HeavyModifications, x => x.FragmentationSequence)
            .SelectMany(async _ => await GetLabeledIonViewModels())
            .Subscribe(livms => LabeledIonViewModels = livms);
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="FragmentationSequenceViewModel"/> class.
        /// </summary>
        public FragmentationSequenceViewModel()
        {
            FragmentationSequence = new FragmentationSequence(
                new Sequence(new List <AminoAcid>()),
                1,
                null,
                ActivationMethod.HCD);

            var baseIonTypes = BaseIonType.AllBaseIonTypes.Select(
                bit =>
                new BaseIonTypeViewModel
            {
                BaseIonType = bit,
                IsSelected  = bit == BaseIonType.B || bit == BaseIonType.Y
            });

            BaseIonTypes = new ReactiveList <BaseIonTypeViewModel>(baseIonTypes)
            {
                ChangeTrackingEnabled = true
            };

            NeutralLosses = new ReactiveList <NeutralLossViewModel>
            {
                new NeutralLossViewModel {
                    NeutralLoss = NeutralLoss.NoLoss, IsSelected = true
                },
                new NeutralLossViewModel {
                    NeutralLoss = NeutralLoss.H2O
                },
                new NeutralLossViewModel {
                    NeutralLoss = NeutralLoss.NH3
                }
            };

            NeutralLosses.ChangeTrackingEnabled = true;

            HeavyModifications   = new SearchModification[0];
            LabeledIonViewModels = new LabeledIonViewModel[0];
            SelectedIonTypes     = new IonType[0];

            AddPrecursorIons = true;

            // HideAllIonsCommand deselects all ion types and neutral losses.
            HideAllIonsCommand = ReactiveCommand.Create(() =>
            {
                AddPrecursorIons = false;
                foreach (var baseIonType in BaseIonTypes)
                {
                    baseIonType.IsSelected = false;
                }

                foreach (var neutralLoss in NeutralLosses)
                {
                    neutralLoss.IsSelected = neutralLoss.NeutralLoss == NeutralLoss.NoLoss && neutralLoss.IsSelected;
                }
            });

            // When Base Ion Types are selected/deselected, update ion types.
            BaseIonTypes.ItemChanged.Where(x => x.PropertyName == "IsSelected")
            .Select(_ => GetIonTypes())
            .Subscribe(ionTypes => SelectedIonTypes = ionTypes);

            // When Neutral Losses are selected/deselected, update ion types
            NeutralLosses.ItemChanged.Where(x => x.PropertyName == "IsSelected")
            .Select(_ => GetIonTypes())
            .Subscribe(ionTypes => SelectedIonTypes = ionTypes);

            // When FragmentationSequence is set, select IonTypes for ActivationMethod.
            this.WhenAnyValue(x => x.FragmentationSequence)
            .Where(fragSeq => fragSeq != null)
            .Subscribe(fragSeq => SetActivationMethod(fragSeq.ActivationMethod));

            // When fragmentation sequence changes, update labeled ions
            this.WhenAnyValue(x => x.FragmentationSequence, x => x.SelectedIonTypes, x => x.HeavyModifications, x => x.AddPrecursorIons)
            .SelectMany(async _ => await GetLabeledIonViewModels())
            .Subscribe(livms => LabeledIonViewModels = livms);

            SelectAllIonsCommand = ReactiveCommand.Create(() =>
            {
                foreach (var ion in BaseIonTypes)
                {
                    ion.IsSelected = true;
                }

                AddPrecursorIons = true;
            });

            IcParameters.Instance.WhenAnyValue(x => x.CidHcdIonTypes, x => x.EtdIonTypes)
            .Throttle(TimeSpan.FromMilliseconds(50), RxApp.TaskpoolScheduler)
            .Where(_ => FragmentationSequence != null)
            .Subscribe(_ => SetActivationMethod(FragmentationSequence.ActivationMethod));
        }