Ejemplo n.º 1
0
            public static void SetComponentEnabledStateForModeUI(Component component, bool isDesired)
            {
                if (component is ToolStripMenuItem item)
                {
                    item.Visible = isDesired;
                    return;
                }

                if (component is TabPage tabPage)
                {
                    var parent = tabPage.Parent as TabControl;
                    if (parent != null)
                    {
                        if (!isDesired)
                        {
                            parent.TabPages.Remove(tabPage);
                        }
                        return;
                    }
                }

                if (component is Control ctrl)
                {
                    ctrl.Visible = isDesired;
                    return;
                }

                Assume.Fail();
            }
Ejemplo n.º 2
0
        public static SpectrumPeakAnnotation Create(SmallMoleculeLibraryAttributes mol, Adduct adduct, string comment, double?mzTheoretical)
        {
            double?massTheoretical = mzTheoretical.HasValue ? adduct.MassFromMz(mzTheoretical.Value, MassType.Monoisotopic).Value : (double?)null;
            var    ion             = new CustomIon(mol, adduct, massTheoretical);

            if ((mzTheoretical ?? 0.0) > 0)
            {
                if (Equals(ion.MonoisotopicMassMz, 0.0))
                {
                    // We didn't have enough info to calculate mz, use the provided theoretical value
                    var massMono    = adduct.MassFromMz(mzTheoretical.Value, MassType.Monoisotopic);
                    var massAverage = adduct.MassFromMz(mzTheoretical.Value, MassType.Average);
                    ion = new CustomIon(ion.GetSmallMoleculeLibraryAttributes(), ion.Adduct, massMono, massAverage);
                }
                else
                {
                    // Check our calculated value against provided theoretical value, allowing quite a lot of wiggle (not everybody is using the same precision out there)
                    var delta = .5; // Generous error for sanity check
                    if (Math.Abs(ion.MonoisotopicMassMz - mzTheoretical.Value) > delta)
                    {
                        Assume.Fail(string.Format(@"SpectrumPeakAnnotation: mzTheoretical {0} and mzActual {1} disagree by more than {2} in {3} {4}",
                                                  mzTheoretical, ion.MonoisotopicMassMz, delta, ion, comment ?? string.Empty));
                    }
                }
            }
            return(ion.IsEmpty && string.IsNullOrEmpty(comment) ?
                   EMPTY :
                   new SpectrumPeakAnnotation(ion, comment));
        }
Ejemplo n.º 3
0
        private void WriteData(Block block, FileStream fileStream)
        {
            // Create back link to previous spilled block.
            var lastFilePosition = new[] { _filePosition };

            _filePosition = (int)fileStream.Position;
            FastWrite.WriteInts(fileStream.SafeFileHandle, lastFilePosition, 0, 1);

            // Write one data block.
            if (typeof(TData) == typeof(short))
            {
                FastWrite.WriteShorts(fileStream.SafeFileHandle, (short[])(object)block._data, 0, _blockSize);
            }
            else if (typeof(TData) == typeof(int))
            {
                FastWrite.WriteInts(fileStream.SafeFileHandle, (int[])(object)block._data, 0, _blockSize);
            }
            else if (typeof(TData) == typeof(float))
            {
                FastWrite.WriteFloats(fileStream.SafeFileHandle, (float[])(object)block._data, 0, _blockSize);
            }
            else
            {
                Assume.Fail();
            }
        }
Ejemplo n.º 4
0
        public IProgressStatus Complete()
        {
            var notFinal = ProgressList.Where(s => !s.IsFinal).ToArray();

            if (notFinal.Any())
            {
                Assume.Fail(TextUtil.LineSeparate("Completing with non-final status:",                                                                                    // Not L10N
                                                  TextUtil.LineSeparate(notFinal.Select(s => string.Format("{0} {1}% - {2}", s.State, s.PercentComplete, s.FilePath))))); // Not L10N
            }
            return(ChangeProp(ImClone(this), s => s._complete = true));
        }
Ejemplo n.º 5
0
            // For all items in a menu, attempt to take a string like "{0} peptides" and return one like "{0} molecules" if menu item is not purely proteomic
            // Update keyboard accelerators as needed
            public static void TranslateMenuItems(ToolStripItemCollection items, SrmDocument.DOCUMENT_TYPE modeUI, ModeUIExtender extender)
            {
                var mapper = new PeptideToMoleculeTextMapper(modeUI, extender);

                if (items != null)
                {
                    mapper.FindInUseKeyboardAccelerators(items);
                    var activeItems = new List <ToolStripItem>();
                    for (int i = 0; i < items.Count; i++)
                    {
                        var item = items[i];
                        ModeUIExtender.MODE_UI_HANDLING_TYPE handlingType;
                        if (!mapper.HandledComponents.TryGetValue(item, out handlingType))
                        {
                            handlingType = ModeUIExtender.MODE_UI_HANDLING_TYPE.auto;
                        }

                        bool isActive;
                        switch (modeUI)
                        {
                        case SrmDocument.DOCUMENT_TYPE.proteomic:
                            isActive = handlingType != ModeUIExtender.MODE_UI_HANDLING_TYPE.small_mol &&
                                       handlingType != ModeUIExtender.MODE_UI_HANDLING_TYPE.small_mol_only &&
                                       handlingType != ModeUIExtender.MODE_UI_HANDLING_TYPE.mixed_only;
                            break;

                        case SrmDocument.DOCUMENT_TYPE.small_molecules:
                            isActive = handlingType != ModeUIExtender.MODE_UI_HANDLING_TYPE.proteomic &&
                                       handlingType != ModeUIExtender.MODE_UI_HANDLING_TYPE.mixed_only;
                            break;

                        case SrmDocument.DOCUMENT_TYPE.mixed:
                            isActive = handlingType != ModeUIExtender.MODE_UI_HANDLING_TYPE.small_mol_only;
                            break;

                        default:
                            isActive = false;
                            Assume.Fail(@"unknown UI mode");
                            break;
                        }

                        if (isActive)
                        {
                            activeItems.Add(item);
                        }
                        item.Visible = isActive;
                    }
                    mapper.Translate(activeItems); // Update the menu items that aren't inherently wrong for current UI mode
                }
            }
        private XmlReader HandleMassOnlyDeclarations(ref Peptide peptide)
        {
            for (var retry = 0; retry < 4; retry++)                                                                      // Looking for a common mass and set of adducts that all agree
            {
                var adjustParentMass = retry < 2;                                                                        // Do/don't try adjusting the neutral mass as if it had proton gain or loss built in
                var assumeProtonated = retry % 2 == 0;                                                                   // Do/don't try [M+H] vs [M+]
                foreach (var detail in _precursorRawDetails.OrderBy(d => d._declaredHeavy ? 1 : 0, SortOrder.Ascending)) // Look at lights first
                {
                    var parentMassAdjustment = adjustParentMass
                        ? Adduct.NonProteomicProtonatedFromCharge(detail._declaredCharge).ApplyToMass(TypedMass.ZERO_MONO_MASSH)
                        : TypedMass.ZERO_MONO_MASSH;
                    var parentMonoisotopicMass = ProposedMolecule.MonoisotopicMass - parentMassAdjustment;
                    if (_precursorRawDetails.TrueForAll(d =>
                    {
                        var adduct = assumeProtonated
                            ? Adduct.NonProteomicProtonatedFromCharge(d._declaredCharge)
                            : Adduct.FromChargeNoMass(d._declaredCharge);
                        if (d._declaredHeavy)
                        {
                            var unexplainedMass = adduct.MassFromMz(d._declaredMz, MassType.Monoisotopic) - parentMonoisotopicMass;
                            adduct = adduct.ChangeIsotopeLabels(unexplainedMass, _mzDecimalPlaces);
                        }
                        d._proposedAdduct = adduct;
                        return(Math.Abs(d._declaredMz - d._proposedAdduct.MzFromNeutralMass(parentMonoisotopicMass)) <= MzToler);
                    }))
                    {
                        var parentAverageMass = ProposedMolecule.AverageMass - parentMassAdjustment;
                        ProposedMolecule = new CustomMolecule(parentMonoisotopicMass, parentAverageMass,
                                                              peptide.CustomMolecule.Name);
                        return(UpdatePeptideAndInsertAdductsInXML(ref peptide, _precursorRawDetails.Select(d => d._proposedAdduct)));
                    }
                }
            }

            // Unexplained masses can be expressed as mass labels
            if (_precursorRawDetails.TrueForAll(d =>
            {
                var adduct = Adduct.FromChargeNoMass(d._declaredCharge);
                var unexplainedMass = adduct.MassFromMz(d._declaredMz, MassType.Monoisotopic) - ProposedMolecule.MonoisotopicMass;
                d._proposedAdduct = adduct.ChangeIsotopeLabels(unexplainedMass, _mzDecimalPlaces);
                return(Math.Abs(d._declaredMz - d._proposedAdduct.MzFromNeutralMass(ProposedMolecule.MonoisotopicMass)) <= MzToler);
            }))
            {
                return(UpdatePeptideAndInsertAdductsInXML(ref peptide, _precursorRawDetails.Select(d => d._proposedAdduct)));
            }

            // Should never arrive here
            Assume.Fail("Unable to to deduce adducts and common molecule for " + peptide); // Not L10N
            return(UpdatePeptideAndInsertAdductsInXML(ref peptide, _precursorRawDetails.Select(d => d._nominalAdduct)));
        }
Ejemplo n.º 7
0
            public TypedMass GetIonMass(IonType ionType, int ionIndex)
            {
                switch (ionType)
                {
                case IonType.precursor:
                    return(PrecursorMass);

                case IonType.custom:
                    Assume.Fail();
                    break;
                }

                return(FragmentMasses[ionType, ionIndex]);
            }
Ejemplo n.º 8
0
        private void CheckRefSpectra(IList <DbRefSpectra> spectra, string name, string formula, string precursorAdduct,
                                     double precursorMz, ushort numPeaks, string[] fragmentNames = null,
                                     double?ionMobility = null, double?ionMobilityHighEnergyOffset = null)
        {
            if (_convertedFromPeptides)
            {
                name = RefinementSettings.TestingConvertedFromProteomicPeptideNameDecorator + name;
            }
            for (var i = 0; i < spectra.Count; i++)
            {
                var spectrum = spectra[i];
                if (spectrum.MoleculeName.Equals(name) &&
                    spectrum.ChemicalFormula.Equals(formula) &&
                    spectrum.PrecursorCharge.Equals(Adduct.FromStringAssumeProtonated(precursorAdduct).AdductCharge) &&
                    spectrum.PrecursorAdduct.Equals(precursorAdduct) &&
                    Math.Abs(spectrum.PrecursorMZ - precursorMz) < 0.001 &&
                    spectrum.NumPeaks.Equals(numPeaks))
                {
                    // Found the item - check its fragment info if provided
                    // This demonstrates fix for "Issue 689: File > Export > Spectral Library losing information from small molecule documents",
                    // point 3 "Ion annotations do not preserve the ion names from the document but instead always use 'ion[mass]' for the annotations
                    // when the document gave them names."
                    if (fragmentNames != null)
                    {
                        Assume.AreEqual(fragmentNames.Length, spectrum.PeakAnnotations.Count);
                        foreach (var annotation in spectrum.PeakAnnotations)
                        {
                            Assume.IsTrue(fragmentNames.Contains(annotation.Name));
                        }
                    }

                    if (ionMobility.HasValue)
                    {
                        AssertEx.AreEqualNullable(spectrum.IonMobility, ionMobility, .00001);
                        if (ionMobilityHighEnergyOffset.HasValue)
                        {
                            AssertEx.AreEqualNullable(spectrum.IonMobilityHighEnergyOffset, ionMobilityHighEnergyOffset, .00001);
                        }
                    }

                    // Item is OK, remove from further searches
                    spectra.RemoveAt(i);
                    return;
                }
            }
            Assume.Fail(string.Format("{0}, {1}, precursor charge {2}, precursor m/z {3}, with {4} peaks not found", name, formula, precursorAdduct, precursorMz, numPeaks));
        }
Ejemplo n.º 9
0
        public bool IsReadyForUniquenessFilter(PeptideFilter.PeptideUniquenessConstraint constraint)
        {
            switch (constraint)
            {
            case PeptideFilter.PeptideUniquenessConstraint.none:
            case PeptideFilter.PeptideUniquenessConstraint.protein:
                return(true);

            case PeptideFilter.PeptideUniquenessConstraint.gene:
            case PeptideFilter.PeptideUniquenessConstraint.species:
                return(!NeedsProteinMetadataSearch);

            default:
                Assume.Fail();
                return(false);     // Should never be here
            }
        }
Ejemplo n.º 10
0
        public static CustomMolecule FromTSV(string val)
        {
            var vals    = val.FromEscapedTSV();
            var name    = vals.Length > 0 ? vals[0] : null;
            var formula = vals.Length > 1 ? vals[1] : null;
            // ReSharper disable PossibleNullReferenceException
            var keysTSV = vals.Length > 2 ? val.Substring(name.Length + formula.Length + 2) : null;

            // ReSharper restore PossibleNullReferenceException
            if (formula == null && name != null && name.StartsWith(INVARIANT_NAME_DETAIL))
            {
                // Looks like a mass-only description
                Regex r = new Regex(massFormatRegex, RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.CultureInvariant);
                Match m = r.Match(val);
                if (m.Success)
                {
                    try
                    {
                        var massMono = new TypedMass(double.Parse(m.Groups[1].Value, CultureInfo.InvariantCulture), MassType.Monoisotopic);
                        var massAvg  = new TypedMass(double.Parse(m.Groups[2].Value, CultureInfo.InvariantCulture), MassType.Average);
                        return(new CustomMolecule(massMono, massAvg));
                    }
                    catch
                    {
                        Assume.Fail("unable to read custom molecule information"); // Not L10N
                    }
                }
            }
            else if (formula != null && formula.Contains("/")) // Not L10N
            {
                // "formula" is actually mono and average masses
                try
                {
                    var values   = formula.Split('/');
                    var massMono = new TypedMass(double.Parse(values[0], CultureInfo.InvariantCulture), MassType.Monoisotopic);
                    var massAvg  = new TypedMass(double.Parse(values[1], CultureInfo.InvariantCulture), MassType.Average);
                    return(new CustomMolecule(massMono, massAvg, name, new MoleculeAccessionNumbers(keysTSV)));
                }
                catch
                {
                    Assume.Fail("unable to read custom molecule information"); // Not L10N
                }
            }
            return(new CustomMolecule(formula, null, null, name, new MoleculeAccessionNumbers(keysTSV)));
        }
 private static void CheckRefSpectra(IList <DbRefSpectra> spectra, string name, string formula, string precursorAdduct, double precursorMz, ushort numPeaks)
 {
     name = RefinementSettings.TestingConvertedFromProteomicPeptideNameDecorator + name;
     for (var i = 0; i < spectra.Count; i++)
     {
         var spectrum = spectra[i];
         if (spectrum.MoleculeName.Equals(name) &&
             spectrum.ChemicalFormula.Equals(formula) &&
             spectrum.PrecursorCharge.Equals(Adduct.FromStringAssumeProtonated(precursorAdduct).AdductCharge) &&
             spectrum.PrecursorAdduct.Equals(precursorAdduct) &&
             Math.Abs(spectrum.PrecursorMZ - precursorMz) < 0.001 &&
             spectrum.NumPeaks.Equals(numPeaks))
         {
             spectra.RemoveAt(i);
             return;
         }
     }
     Assume.Fail(string.Format("{0}, {1}, precursor charge {2}, precursor m/z {3}, with {4} peaks not found", name, formula, precursorAdduct, precursorMz, numPeaks));
 }
Ejemplo n.º 12
0
        /// <summary>
        /// Reconstitute data from memory and disk.
        /// </summary>
        public TData[] ToArray(byte[] bytes)
        {
            // Return final cached array.
            if (_blockIndex < 0)
            {
                return(_block._data);
            }

            // Allocate final array.
            int dest  = Count;
            var array = new TData[dest];

            if (dest == 0)
            {
                return(array);
            }
            int length = (_blockIndex > 0) ? _blockIndex : _blockSize;

            // Copy data from memory blocks.
            while (_block != null)
            {
                dest -= length;
                Array.Copy(_block._data, 0, array, dest, length);
                _block = _block._previousBlock;
                length = _blockSize;
            }

            Assume.IsTrue(bytes != null || _blocksOnDisk == 0);

            // Copy data that was spilled.
            while (_blocksOnDisk > 0)
            {
                dest -= _blockSize;
                int source = _filePosition;
                // ReSharper disable once AssignNullToNotNullAttribute
                _filePosition = BitConverter.ToInt32(bytes, source);
                source       += sizeof(int);
                int dest2 = dest;

                // Convert byte data.
                if (typeof(TData) == typeof(short))
                {
                    for (int j = 0; j < _blockSize; j++)
                    {
                        // ReSharper disable once AssignNullToNotNullAttribute
                        array[dest2++] = (TData)(object)BitConverter.ToInt16(bytes, source);
                        source        += sizeof(short);
                    }
                }
                else if (typeof(TData) == typeof(int))
                {
                    for (int j = 0; j < _blockSize; j++)
                    {
                        // ReSharper disable once AssignNullToNotNullAttribute
                        array[dest2++] = (TData)(object)BitConverter.ToInt32(bytes, source);
                        source        += sizeof(int);
                    }
                }
                else if (typeof(TData) == typeof(float))
                {
                    for (int j = 0; j < _blockSize; j++)
                    {
                        // ReSharper disable once AssignNullToNotNullAttribute
                        array[dest2++] = (TData)(object)BitConverter.ToSingle(bytes, source);
                        source        += sizeof(float);
                    }
                }
                else
                {
                    Assume.Fail();
                }
                _blocksOnDisk--;
            }

            // Cache the final array in case this collector is shared (i.e., shared times).
            _block      = new Block(array, null);
            _blockIndex = -1;

            return(array);
        }
Ejemplo n.º 13
0
        public void OkDialog()
        {
            var helper = new MessageBoxHelper(this);
            var charge = 0;

            if (textCharge.Visible &&
                !helper.ValidateSignedNumberTextBox(textCharge, _minCharge, _maxCharge, out charge))
            {
                return;
            }
            var adduct = Adduct.NonProteomicProtonatedFromCharge(charge);

            if (RetentionTimeWindow.HasValue && !RetentionTime.HasValue)
            {
                helper.ShowTextBoxError(textRetentionTimeWindow,
                                        Resources
                                        .Peptide_ExplicitRetentionTimeWindow_Explicit_retention_time_window_requires_an_explicit_retention_time_value_);
                return;
            }
            if (Adduct.IsEmpty || Adduct.AdductCharge != adduct.AdductCharge)
            {
                Adduct =
                    adduct; // Note: order matters here, this settor indirectly updates _formulaBox.MonoMass when formula is empty
            }
            if (string.IsNullOrEmpty(_formulaBox.NeutralFormula))
            {
                // Can the text fields be understood as mz?
                if (!_formulaBox.ValidateAverageText(helper))
                {
                    return;
                }
                if (!_formulaBox.ValidateMonoText(helper))
                {
                    return;
                }
            }
            var monoMass    = new TypedMass(_formulaBox.MonoMass ?? 0, MassType.Monoisotopic);
            var averageMass = new TypedMass(_formulaBox.AverageMass ?? 0, MassType.Average);

            if (monoMass < CustomMolecule.MIN_MASS || averageMass < CustomMolecule.MIN_MASS)
            {
                _formulaBox.ShowTextBoxErrorFormula(helper,
                                                    string.Format(
                                                        Resources
                                                        .EditCustomMoleculeDlg_OkDialog_Custom_molecules_must_have_a_mass_greater_than_or_equal_to__0__,
                                                        CustomMolecule.MIN_MASS));
                return;
            }
            if (monoMass > CustomMolecule.MAX_MASS || averageMass > CustomMolecule.MAX_MASS)
            {
                _formulaBox.ShowTextBoxErrorFormula(helper,
                                                    string.Format(
                                                        Resources
                                                        .EditCustomMoleculeDlg_OkDialog_Custom_molecules_must_have_a_mass_less_than_or_equal_to__0__,
                                                        CustomMolecule.MAX_MASS));
                return;
            }

            if ((_transitionSettings != null) &&
                (!_transitionSettings.IsMeasurablePrecursor(
                     adduct.MzFromNeutralMass(monoMass, MassType.Monoisotopic)) ||
                 !_transitionSettings.IsMeasurablePrecursor(adduct.MzFromNeutralMass(averageMass, MassType.Average))))
            {
                _formulaBox.ShowTextBoxErrorFormula(helper,
                                                    Resources
                                                    .SkylineWindow_AddMolecule_The_precursor_m_z_for_this_molecule_is_out_of_range_for_your_instrument_settings_);
                return;
            }

            // Ion mobility value must have ion mobility units
            if (textIonMobility.Visible && IonMobility.HasValue)
            {
                if (IonMobilityUnits == eIonMobilityUnits.none)
                {
                    helper.ShowTextBoxError(textIonMobility, Resources.EditCustomMoleculeDlg_OkDialog_Please_specify_the_ion_mobility_units_);
                    comboBoxIonMobilityUnits.Focus();
                    return;
                }

                if (IonMobility.Value == 0 ||
                    (IonMobility.Value < 0 && !IonMobilityFilter.AcceptNegativeMobilityValues(IonMobilityUnits)))
                {
                    helper.ShowTextBoxError(textIonMobility,
                                            string.Format(Resources.SmallMoleculeTransitionListReader_ReadPrecursorOrProductColumns_Invalid_ion_mobility_value__0_, IonMobility));
                    textIonMobility.Focus();
                    return;
                }
            }
            if (_usageMode == UsageMode.precursor)
            {
                // Only the adduct should be changing
                SetResult(_resultCustomMolecule, Adduct);
            }
            else if (!string.IsNullOrEmpty(_formulaBox.NeutralFormula))
            {
                try
                {
                    var name = textName.Text;
                    if (string.IsNullOrEmpty(name))
                    {
                        name = _formulaBox.NeutralFormula; // Clip off any adduct description
                    }
                    SetResult(new CustomMolecule(_formulaBox.NeutralFormula, name), Adduct);
                }
                catch (InvalidDataException x)
                {
                    _formulaBox.ShowTextBoxErrorFormula(helper, x.Message);
                    return;
                }
            }
            else
            {
                SetResult(new CustomMolecule(monoMass, averageMass, textName.Text), Adduct);
            }
            // Did user change the list of heavy labels?
            if (_driverLabelType != null)
            {
                // This is the only thing the user may have altered
                var newHeavyMods = _driverLabelType.GetHeavyModifications().ToArray();
                if (!ArrayUtil.EqualsDeep(newHeavyMods, _peptideSettings.Modifications.HeavyModifications))
                {
                    var labelTypes = _peptideSettings.Modifications.InternalStandardTypes.Where(t =>
                                                                                                newHeavyMods.Any(m => Equals(m.LabelType, t))).ToArray();
                    if (labelTypes.Length == 0)
                    {
                        labelTypes = new[] { newHeavyMods.First().LabelType }
                    }
                    ;

                    PeptideModifications modifications = new PeptideModifications(
                        _peptideSettings.Modifications.StaticModifications,
                        _peptideSettings.Modifications.MaxVariableMods,
                        _peptideSettings.Modifications.MaxNeutralLosses,
                        newHeavyMods,
                        labelTypes);
                    var         settings    = _peptideSettings.ChangeModifications(modifications);
                    SrmSettings newSettings = _parent.DocumentUI.Settings.ChangePeptideSettings(settings);
                    if (!_parent.ChangeSettings(newSettings, true))
                    {
                        // Not expected, since we checked for a change before calling
                        // Otherwise, this is very confusing. The form just refuses to go away
                        // We would prefer to get an unhandled exception and fix this
                        Assume.Fail();
                        return;
                    }
                    _peptideSettings = newSettings.PeptideSettings;
                }
            }

            // See if this combination of charge and label would conflict with any existing transition groups
            if (_existingIds != null && _existingIds.Any(t =>
            {
                var transitionGroup = t as TransitionGroup;
                return(transitionGroup != null && Equals(transitionGroup.LabelType, IsotopeLabelType) &&
                       Equals(transitionGroup.PrecursorAdduct.AsFormula(),
                              Adduct
                              .AsFormula()) &&  // Compare AsFormula so proteomic and non-proteomic protonation are seen as same thing
                       !ReferenceEquals(t, _initialId));
            }))
            {
                helper.ShowTextBoxError(textName,
                                        Resources
                                        .EditCustomMoleculeDlg_OkDialog_A_precursor_with_that_adduct_and_label_type_already_exists_,
                                        textName.Text);
                return;
            }

            // See if this would conflict with any existing transitions
            if (_existingIds != null && (_existingIds.Any(t =>
            {
                var transition = t as Transition;
                return(transition != null && (Equals(transition.Adduct.AsFormula(), Adduct.AsFormula()) &&
                                              Equals(transition.CustomIon, ResultCustomMolecule)) &&
                       !ReferenceEquals(t, _initialId));
            })))
            {
                helper.ShowTextBoxError(textName,
                                        Resources.EditCustomMoleculeDlg_OkDialog_A_similar_transition_already_exists_, textName.Text);
                return;
            }
            DialogResult = DialogResult.OK;
        }