public IEnumerable <PeptideDocNode> CreatePeptideDocNodes(SrmSettings settings, bool useFilter, Target peptideSequence) { PeptideSettings pepSettings = settings.PeptideSettings; DigestSettings digest = pepSettings.DigestSettings; IPeptideFilter filter = (useFilter ? settings : PeptideFilter.UNFILTERED); int? maxLen = null, minLen = null; var pick = pepSettings.Libraries.Pick; if (useFilter && pick != PeptidePick.library && pick != PeptidePick.either) { // CONSIDER(brendanx): It should be possible to get min and max length from libraries maxLen = pepSettings.Filter.MaxPeptideLength; minLen = pepSettings.Filter.MinPeptideLength; } foreach (var peptide in pepSettings.Enzyme.Digest(this, digest, maxLen, minLen)) { if (null != peptideSequence && !Equals(peptideSequence, peptide.Target)) { continue; } foreach (var nodePep in peptide.CreateDocNodes(settings, filter)) { yield return(nodePep); } } }
public void AddModification(StaticMod mod, ModType type) { if (mod == null) { return; } ImportPeptideSearch.UserDefinedTypedMods.Add(mod); PeptideSettings newPeptideSettings = SkylineWindow.Document.Settings.PeptideSettings; var newMods = new List <StaticMod>( (type == ModType.structural ? newPeptideSettings.Modifications.StaticModifications : newPeptideSettings.Modifications.HeavyModifications) ) { mod }; newPeptideSettings = (type == ModType.structural) ? newPeptideSettings.ChangeModifications(newPeptideSettings.Modifications.ChangeStaticModifications(newMods)) : newPeptideSettings.ChangeModifications(newPeptideSettings.Modifications.ChangeHeavyModifications(newMods)); SkylineWindow.ChangeSettings(SkylineWindow.Document.Settings.ChangePeptideSettings(newPeptideSettings), true, string.Format(Resources.MatchModificationsControl_AddModification_Add__0__modification__1_, type, mod.Name)); SkylineWindow.Document.Settings.UpdateDefaultModifications(false); FillLists(SkylineWindow.Document); }
// N.B. leaving this level of indirection in place as it will be useful in speeding up the Unique Peptides dialog /// <summary> /// Examine the background proteome for uniqueness information about the peptides of interest /// </summary> /// <param name="peptidesOfInterest">this is a dict instead of a list only because upstream callers have already prepared this, which can be large and expensive to construct</param> /// <param name="enzyme">how we digest</param> /// <param name="settings">details like max missed cleavages</param> /// <param name="progressMonitor">cancellation checker</param> /// <returns></returns> public Dictionary <string, DigestionPeptideStatsDetailed> GetPeptidesAppearances( Dictionary <Target, bool> peptidesOfInterest, Enzyme enzyme, PeptideSettings settings, SrmSettingsChangeMonitor progressMonitor) { if (string.IsNullOrEmpty(DatabasePath)) { return(null); } var results = peptidesOfInterest.ToDictionary(pep => pep.Key.Sequence, pep => new DigestionPeptideStatsDetailed()); if (results.Count == 0) { return(results); } var protease = new ProteaseImpl(enzyme); var maxPeptideLength = peptidesOfInterest.Max(p => p.Key.Sequence.Length); // No interest in any peptide longer than the longest one of interest const int DIGEST_CHUNKSIZE = 1000; // Check for cancel every N proteins var proteinCount = 0; using (var proteomeDb = OpenProteomeDb()) { var goal = Math.Max(proteomeDb.GetProteinCount(), 1); var batchCount = 0; var minimalProteinInfos = new ProteomeDb.MinimalProteinInfo[DIGEST_CHUNKSIZE]; foreach (var minimalProteinInfo in proteomeDb.GetMinimalProteinInfo()) // Get list of sequence, proteinID, gene, species from the protdb file { minimalProteinInfos[batchCount++] = minimalProteinInfo; var pct = Math.Max(1, 100 * proteinCount++ / goal); // Show at least a little progressat start to give user hope if (batchCount == 0 && !UpdateProgressAndCheckForCancellation(progressMonitor, pct)) { return(null); } else if (((minimalProteinInfo == null) && --batchCount > 0) || batchCount == DIGEST_CHUNKSIZE) { ParallelEx.For(0, batchCount, ii => { var protein = minimalProteinInfos[ii]; foreach (var peptide in protease.DigestSequence(protein.Sequence, settings.DigestSettings.MaxMissedCleavages, maxPeptideLength)) { DigestionPeptideStatsDetailed appearances; if (results.TryGetValue(peptide.Sequence, out appearances)) { lock (appearances) { appearances.Proteins.Add(protein.Id); appearances.Genes.Add(protein.Gene); // HashSet eliminates duplicates appearances.Species.Add(protein.Species); // HashSet eliminates duplicates } } } }); batchCount = 0; } } } return(results); }
/// <summary> /// Get, create, or update the current dictionary that gives uniqueness information for peptides of interest. /// </summary> /// <param name="peptideSettings">enzyme info in case we need to perform digestion</param> /// <param name="peptidesOfInterest">this is a dictionary instead of a list only because we need an efficient lookup, and caller will already have created this which can be large and expensive to construct.</param> /// <param name="progressMonitor">cancellation checker</param> /// <returns>updated peptide settings with uniqueness information for peptides of interest</returns> public Dictionary <Target, DigestionPeptideStats> GetUniquenessDict(PeptideSettings peptideSettings, Dictionary <Target, bool> peptidesOfInterest, SrmSettingsChangeMonitor progressMonitor) { // Do we have a cached dictionary suitable to the task? var enzyme = peptideSettings.Enzyme; if (!(enzyme.Name != _enzymeNameForPeptideUniquenessDictDigest || peptidesOfInterest.Keys.Any(pep => !_peptideUniquenessDict.ContainsKey(pep)))) { return(_peptideUniquenessDict); // No change needed } if (!_parent.UpdateProgressAndCheckForCancellation(progressMonitor, 0)) { return(null); // Cancelled } // Any peptides we were interested in before (ie in the current dict if any) are likely still // interesting in future calls, even if not of immediate interest foreach (var seq in _peptideUniquenessDict.Where(i => !peptidesOfInterest.ContainsKey(i.Key))) { peptidesOfInterest.Add(seq.Key, true); } var newDict = _parent.GetPeptidesAppearanceCounts(peptidesOfInterest, enzyme, peptideSettings, progressMonitor); if (newDict == null) { return(null); // Cancelled } if (!Equals(enzyme.Name, _enzymeNameForPeptideUniquenessDictDigest)) { _peptideUniquenessDict = new Dictionary <Target, DigestionPeptideStats>(); } else { _peptideUniquenessDict = _peptideUniquenessDict.ToDictionary(s => s.Key, s => s.Value); } foreach (var pair in newDict) { if (!_peptideUniquenessDict.ContainsKey(pair.Key)) { _peptideUniquenessDict.Add(pair.Key, pair.Value); } else { _peptideUniquenessDict[pair.Key] = pair.Value; } } _enzymeNameForPeptideUniquenessDictDigest = enzyme.Name; if (!_parent.UpdateProgressAndCheckForCancellation(progressMonitor, 100)) { return(null); // Cancelled } return(_peptideUniquenessDict); }
public DigestHelper(BackgroundProteomeManager manager, IDocumentContainer container, SrmDocument document, PeptideSettings settings, string nameProteome, string pathProteome, bool isTemporary) { _manager = manager; _container = container; _document = document; _settings = settings; _nameProteome = nameProteome; _pathProteome = pathProteome; _isTemporary = isTemporary; }
public IEnumerable <PeptideDocNode> CreatePeptideDocNodes(SrmSettings settings, bool useFilter, string peptideSequence) { PeptideSettings pepSettings = settings.PeptideSettings; DigestSettings digest = pepSettings.DigestSettings; IPeptideFilter filter = (useFilter ? settings : PeptideFilter.UNFILTERED); foreach (var peptide in pepSettings.Enzyme.Digest(this, digest)) { if (null != peptideSequence && peptideSequence != peptide.Sequence) { continue; } foreach (var nodePep in peptide.CreateDocNodes(settings, filter)) { yield return(nodePep); } } }
// For use in PeptideSettingsUI, where we may need to force completion for peptide uniqueness constraints public BackgroundProteome LoadForeground(PeptideSettings settings, SrmSettingsChangeMonitor monitor) { if (monitor.IsCanceled()) { return(null); } Assume.IsTrue(ForegroundLoadRequested); // Caller should have called BeginForegroundLoad() lock (_lockLoadBackgroundProteome) // Wait for background loader, if any, to notice { _monitor = monitor; try { return(Load(null, settings, null, false)); } finally { _monitor = null; } } }
public static string IsNotLoadedExplained(PeptideSettings settings, BackgroundProteome backgroundProteome, bool requireResolvedProteinMetadata) { if (backgroundProteome.IsNone) { return(null); } if (!backgroundProteome.DatabaseValidated) { return("BackgroundProteomeManager: !backgroundProteome.DatabaseValidated"); // Not L10N } if (backgroundProteome.DatabaseInvalid) { return(null); } if (!requireResolvedProteinMetadata || !backgroundProteome.NeedsProteinMetadataSearch) { return(null); } return("BackgroundProteomeManager: NeedsProteinMetadataSearch"); // Not L10N }
public Dictionary <Target, DigestionPeptideStats> GetPeptidesAppearanceCounts(Dictionary <Target, bool> peptidesOfInterest, Enzyme enzyme, PeptideSettings settings, SrmSettingsChangeMonitor progressMonitor) { var appearances = GetPeptidesAppearances(peptidesOfInterest, enzyme, settings, progressMonitor); if (appearances == null) { return(null); // Cancelled } return(appearances.ToDictionary(pep => new Target(pep.Key), pep => new DigestionPeptideStats(pep.Value.Proteins.Count, pep.Value.Genes.Count, pep.Value.Species.Count))); }
/// <summary> /// For creating at the Molecule level (create molecule and first transition group) or modifying at the transition level /// Null values imply "don't ask user for this" /// </summary> public EditCustomMoleculeDlg(SkylineWindow parent, string title, Identity initialId, IEnumerable <Identity> existingIds, int minCharge, int maxCharge, SrmSettings settings, string defaultName, string defaultFormula, int?defaultCharge, ExplicitTransitionGroupValues explicitAttributes, ExplicitRetentionTimeInfo explicitRetentionTime, IsotopeLabelType defaultIsotopeLabelType, bool enableFormulaEditing = true) { Text = title; _parent = parent; _initialId = initialId; _existingIds = existingIds; _minCharge = minCharge; _maxCharge = maxCharge; _transitionSettings = settings != null ? settings.TransitionSettings : null; _peptideSettings = settings != null ? settings.PeptideSettings : null; InitializeComponent(); NameText = defaultName; var needOptionalValuesBox = explicitRetentionTime != null || explicitAttributes != null; var heightDelta = 0; if (explicitAttributes == null) { ResultExplicitTransitionGroupValues = null; labelCollisionEnergy.Visible = false; textCollisionEnergy.Visible = false; labelSLens.Visible = false; textSLens.Visible = false; labelCompensationVoltage.Visible = false; textCompensationVoltage.Visible = false; labelConeVoltage.Visible = false; textConeVoltage.Visible = false; labelDriftTimeHighEnergyOffsetMsec.Visible = false; textDriftTimeHighEnergyOffsetMsec.Visible = false; labelDriftTimeMsec.Visible = false; textDriftTimeMsec.Visible = false; if (needOptionalValuesBox) { // We blanked out everything but the retention time var vmargin = labelRetentionTime.Location.Y; var newHeight = textRetentionTime.Location.Y + textRetentionTime.Height + vmargin; heightDelta = groupBoxOptionalValues.Height - newHeight; groupBoxOptionalValues.Height = newHeight; } } else { ResultExplicitTransitionGroupValues = new ExplicitTransitionGroupValues(explicitAttributes); } string labelAverage = defaultCharge.HasValue ? Resources.EditCustomMoleculeDlg_EditCustomMoleculeDlg_A_verage_m_z_ : Resources.EditCustomMoleculeDlg_EditCustomMoleculeDlg_A_verage_mass_; string labelMono = defaultCharge.HasValue ? Resources.EditCustomMoleculeDlg_EditCustomMoleculeDlg__Monoisotopic_m_z_ : Resources.EditCustomMoleculeDlg_EditCustomMoleculeDlg__Monoisotopic_mass_; _formulaBox = new FormulaBox(Resources.EditMeasuredIonDlg_EditMeasuredIonDlg_Ion__chemical_formula_, labelAverage, labelMono, defaultCharge) { Formula = defaultFormula, Location = new Point(textName.Left, textName.Bottom + 12) }; Controls.Add(_formulaBox); _formulaBox.TabIndex = 2; _formulaBox.Enabled = enableFormulaEditing; bool needCharge = defaultCharge.HasValue; textCharge.Visible = labelCharge.Visible = needCharge; Charge = defaultCharge ?? 0; if (needOptionalValuesBox && !needCharge) { heightDelta += groupBoxOptionalValues.Location.Y - labelCharge.Location.Y; groupBoxOptionalValues.Location = new Point(groupBoxOptionalValues.Location.X, labelCharge.Location.Y); } if (explicitRetentionTime == null) { // Don't ask user for retetention times RetentionTime = null; RetentionTimeWindow = null; labelRetentionTime.Visible = false; labelRetentionTimeWindow.Visible = false; textRetentionTime.Visible = false; textRetentionTimeWindow.Visible = false; if (needOptionalValuesBox) { var rtHeight = labelCollisionEnergy.Location.Y - labelRetentionTimeWindow.Location.Y; groupBoxOptionalValues.Height -= rtHeight; heightDelta += rtHeight; } } else { RetentionTime = explicitRetentionTime.RetentionTime; RetentionTimeWindow = explicitRetentionTime.RetentionTimeWindow; } if (!needOptionalValuesBox) { groupBoxOptionalValues.Visible = false; heightDelta = groupBoxOptionalValues.Height; } // Initialize label if (settings != null && defaultIsotopeLabelType != null) { _driverLabelType = new PeptideSettingsUI.LabelTypeComboDriver(comboIsotopeLabelType, settings.PeptideSettings.Modifications, null, null, null, null) { SelectedName = defaultIsotopeLabelType.Name }; } else { comboIsotopeLabelType.Visible = false; labelIsotopeLabelType.Visible = false; } Height -= heightDelta; }
public void OkDialog() { var helper = new MessageBoxHelper(this); var charge = 0; if (textCharge.Visible && !helper.ValidateSignedNumberTextBox(textCharge, _minCharge, _maxCharge, out charge)) { return; } if (RetentionTimeWindow.HasValue && !RetentionTime.HasValue) { helper.ShowTextBoxError(textRetentionTimeWindow, Resources.Peptide_ExplicitRetentionTimeWindow_Explicit_retention_time_window_requires_an_explicit_retention_time_value_); return; } Charge = charge; // Note: order matters here, this settor indirectly updates _formulaBox.MonoMass when formula is empty if (string.IsNullOrEmpty(_formulaBox.Formula)) { // Can the text fields be understood as mz? if (!_formulaBox.ValidateAverageText(helper)) { return; } if (!_formulaBox.ValidateMonoText(helper)) { return; } } var formula = _formulaBox.Formula; var monoMass = _formulaBox.MonoMass ?? 0; var averageMass = _formulaBox.AverageMass ?? 0; if (monoMass < CustomIon.MIN_MASS || averageMass < CustomIon.MIN_MASS) { _formulaBox.ShowTextBoxErrorFormula(helper, string.Format(Resources.EditCustomMoleculeDlg_OkDialog_Custom_molecules_must_have_a_mass_greater_than_or_equal_to__0__, CustomIon.MIN_MASS)); return; } if (monoMass > CustomIon.MAX_MASS || averageMass > CustomIon.MAX_MASS) { _formulaBox.ShowTextBoxErrorFormula(helper, string.Format(Resources.EditCustomMoleculeDlg_OkDialog_Custom_molecules_must_have_a_mass_less_than_or_equal_to__0__, CustomIon.MAX_MASS)); return; } if ((_transitionSettings != null) && (!_transitionSettings.IsMeasurablePrecursor(BioMassCalc.CalculateIonMz(monoMass, charge)) || !_transitionSettings.IsMeasurablePrecursor(BioMassCalc.CalculateIonMz(averageMass, charge)))) { _formulaBox.ShowTextBoxErrorFormula(helper, Resources.SkylineWindow_AddMolecule_The_precursor_m_z_for_this_molecule_is_out_of_range_for_your_instrument_settings_); return; } if (!string.IsNullOrEmpty(_formulaBox.Formula)) { try { ResultCustomIon = new DocNodeCustomIon(formula, textName.Text); } catch (InvalidDataException x) { _formulaBox.ShowTextBoxErrorFormula(helper, x.Message); return; } } else { ResultCustomIon = new DocNodeCustomIon(monoMass, averageMass, textName.Text); } // Did user change the list of heavy labels? if (_driverLabelType != null) { PeptideModifications modifications = new PeptideModifications( _peptideSettings.Modifications.StaticModifications, _peptideSettings.Modifications.MaxVariableMods, _peptideSettings.Modifications.MaxNeutralLosses, _driverLabelType.GetHeavyModifications(), // This is the only thing the user may have altered _peptideSettings.Modifications.InternalStandardTypes); var settings = _peptideSettings.ChangeModifications(modifications); // Only update if anything changed if (!Equals(settings, _peptideSettings)) { SrmSettings newSettings = _parent.DocumentUI.Settings.ChangePeptideSettings(settings); if (!_parent.ChangeSettings(newSettings, true)) { 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.PrecursorCharge, Charge) && !ReferenceEquals(t, _initialId)); })) { helper.ShowTextBoxError(textName, Resources.EditCustomMoleculeDlg_OkDialog_A_precursor_with_that_charge_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 && ((transition.Charge == Charge) && Equals(transition.CustomIon, ResultCustomIon)) && !ReferenceEquals(t, _initialId)); }))) { helper.ShowTextBoxError(textName, Resources.EditCustomMoleculeDlg_OkDialog_A_similar_transition_already_exists_, textName.Text); return; } DialogResult = DialogResult.OK; }
/// <summary> /// For creating at the Molecule level (create molecule and first transition group) or modifying at the transition level /// Null values imply "don't ask user for this" /// </summary> public EditCustomMoleculeDlg(SkylineWindow parent, UsageMode usageMode, string title, Identity initialId, IEnumerable <Identity> existingIds, int minCharge, int maxCharge, SrmSettings settings, CustomMolecule molecule, Adduct defaultCharge, ExplicitTransitionGroupValues explicitTransitionGroupAttributes, ExplicitTransitionValues explicitTransitionAttributes, ExplicitRetentionTimeInfo explicitRetentionTime, IsotopeLabelType defaultIsotopeLabelType) { Text = title; _parent = parent; _initialId = initialId; _existingIds = existingIds; _minCharge = minCharge; _maxCharge = maxCharge; _transitionSettings = settings != null ? settings.TransitionSettings : null; _peptideSettings = settings != null ? settings.PeptideSettings : null; _resultAdduct = Adduct.EMPTY; _resultCustomMolecule = molecule; _usageMode = usageMode; var enableFormulaEditing = usageMode == UsageMode.moleculeNew || usageMode == UsageMode.moleculeEdit || usageMode == UsageMode.fragment; var enableAdductEditing = usageMode == UsageMode.moleculeNew || usageMode == UsageMode.precursor || usageMode == UsageMode.fragment; var suggestOnlyAdductsWithMass = usageMode != UsageMode.fragment; var needExplicitTransitionValues = usageMode == UsageMode.fragment; var needExplicitTransitionGroupValues = usageMode == UsageMode.moleculeNew || usageMode == UsageMode.precursor; InitializeComponent(); NameText = molecule == null ? String.Empty : molecule.Name; textName.Enabled = usageMode == UsageMode.moleculeNew || usageMode == UsageMode.moleculeEdit || usageMode == UsageMode.fragment; // Can user edit name? var needOptionalValuesBox = explicitRetentionTime != null || explicitTransitionGroupAttributes != null || explicitTransitionAttributes != null; if (!needExplicitTransitionValues) { labelCollisionEnergy.Visible = false; textCollisionEnergy.Visible = false; labelSLens.Visible = false; textSLens.Visible = false; labelConeVoltage.Visible = false; textConeVoltage.Visible = false; labelIonMobilityHighEnergyOffset.Visible = false; textIonMobilityHighEnergyOffset.Visible = false; labelDeclusteringPotential.Visible = false; textDeclusteringPotential.Visible = false; } if (!needExplicitTransitionGroupValues) { labelCCS.Visible = false; textBoxCCS.Visible = false; labelIonMobility.Visible = false; textIonMobility.Visible = false; labelIonMobilityUnits.Visible = false; comboBoxIonMobilityUnits.Visible = false; } var heightDelta = 0; // Initialise the ion mobility units dropdown with L10N values foreach (eIonMobilityUnits t in Enum.GetValues(typeof(eIonMobilityUnits))) { comboBoxIonMobilityUnits.Items.Add(IonMobilityFilter.IonMobilityUnitsL10NString(t)); } if (needOptionalValuesBox) { var newHeight = groupBoxOptionalValues.Height; var movers = new List <Control>(); int offset = 0; if (!needExplicitTransitionGroupValues && !needExplicitTransitionValues) { // We blanked out everything but the retention time newHeight = labelCollisionEnergy.Location.Y; } else if (!needExplicitTransitionGroupValues) { // We need to shift transition-level items up to where retention time was movers.AddRange(new Control[] { textCollisionEnergy, labelCollisionEnergy, textDeclusteringPotential, labelDeclusteringPotential, textSLens, labelSLens, textConeVoltage, labelConeVoltage, textIonMobilityHighEnergyOffset, labelIonMobilityHighEnergyOffset }); labelIonMobilityHighEnergyOffset.Location = labelIonMobility.Location; textIonMobilityHighEnergyOffset.Location = textIonMobility.Location; offset = labelCollisionEnergy.Location.Y - labelRetentionTime.Location.Y; newHeight = textBoxCCS.Location.Y; } else if (!needExplicitTransitionValues) { // We need to shift precursor-level items up to where retention time was movers.AddRange(new Control[] { textBoxCCS, labelCCS, textIonMobility, labelIonMobility, comboBoxIonMobilityUnits, labelIonMobilityUnits }); offset = labelIonMobility.Location.Y - (explicitRetentionTime == null ? labelRetentionTime.Location.Y : labelCollisionEnergy.Location.Y); newHeight = explicitRetentionTime == null ? textSLens.Location.Y : textIonMobility.Location.Y; } foreach (var mover in movers) { mover.Anchor = AnchorStyles.Left | AnchorStyles.Top; mover.Location = new Point(mover.Location.X, mover.Location.Y - offset); } heightDelta = groupBoxOptionalValues.Height - newHeight; groupBoxOptionalValues.Height = newHeight; } ResultExplicitTransitionGroupValues = new ExplicitTransitionGroupValues(explicitTransitionGroupAttributes); ResultExplicitTransitionValues = new ExplicitTransitionValues(explicitTransitionAttributes); string labelAverage = !defaultCharge.IsEmpty ? Resources.EditCustomMoleculeDlg_EditCustomMoleculeDlg_A_verage_m_z_ : Resources.EditCustomMoleculeDlg_EditCustomMoleculeDlg_A_verage_mass_; string labelMono = !defaultCharge.IsEmpty ? Resources.EditCustomMoleculeDlg_EditCustomMoleculeDlg__Monoisotopic_m_z_ : Resources.EditCustomMoleculeDlg_EditCustomMoleculeDlg__Monoisotopic_mass_; var defaultFormula = molecule == null ? string.Empty : molecule.Formula; var transition = initialId as Transition; FormulaBox.EditMode editMode; if (enableAdductEditing && !enableFormulaEditing) { editMode = FormulaBox.EditMode.adduct_only; } else if (!enableAdductEditing && enableFormulaEditing) { editMode = FormulaBox.EditMode.formula_only; } else { editMode = FormulaBox.EditMode.formula_and_adduct; } string formulaBoxLabel; if (defaultCharge.IsEmpty) { formulaBoxLabel = Resources.EditCustomMoleculeDlg_EditCustomMoleculeDlg_Chemi_cal_formula_; } else if (editMode == FormulaBox.EditMode.adduct_only) { var prompt = defaultFormula; if (string.IsNullOrEmpty(defaultFormula) && molecule != null) { // Defined by mass only prompt = molecule.ToString(); } formulaBoxLabel = string.Format(Resources.EditCustomMoleculeDlg_EditCustomMoleculeDlg_Addu_ct_for__0__, prompt); } else { formulaBoxLabel = Resources.EditMeasuredIonDlg_EditMeasuredIonDlg_Ion__chemical_formula_; } double?averageMass = null; double?monoMass = null; if (transition != null && string.IsNullOrEmpty(defaultFormula) && transition.IsCustom()) { averageMass = transition.CustomIon.AverageMass; monoMass = transition.CustomIon.MonoisotopicMass; } else if (molecule != null) { averageMass = molecule.AverageMass; monoMass = molecule.MonoisotopicMass; } _formulaBox = new FormulaBox(false, // Not proteomic, so offer Cl and Br in atoms popup formulaBoxLabel, labelAverage, labelMono, defaultCharge, editMode, suggestOnlyAdductsWithMass) { NeutralFormula = defaultFormula, AverageMass = averageMass, MonoMass = monoMass, Location = new Point(textName.Left, textName.Bottom + 12) }; _formulaBox.ChargeChange += (sender, args) => { if (!_formulaBox.Adduct.IsEmpty) { Adduct = _formulaBox.Adduct; var revisedFormula = _formulaBox.NeutralFormula + Adduct.AdductFormula; if (!Equals(revisedFormula, _formulaBox.Formula)) { _formulaBox.Formula = revisedFormula; } if (string.IsNullOrEmpty(_formulaBox.NeutralFormula) && averageMass.HasValue) { _formulaBox.AverageMass = averageMass; _formulaBox.MonoMass = monoMass; } } }; Controls.Add(_formulaBox); _formulaBox.TabIndex = 2; _formulaBox.Enabled = enableFormulaEditing || enableAdductEditing; Adduct = defaultCharge; var needCharge = !Adduct.IsEmpty; textCharge.Visible = labelCharge.Visible = needCharge; if (needOptionalValuesBox && !needCharge) { heightDelta += groupBoxOptionalValues.Location.Y - labelCharge.Location.Y; groupBoxOptionalValues.Location = new Point(groupBoxOptionalValues.Location.X, labelCharge.Location.Y); } if (explicitRetentionTime == null) { // Don't ask user for retetention times RetentionTime = null; RetentionTimeWindow = null; labelRetentionTime.Visible = false; labelRetentionTimeWindow.Visible = false; textRetentionTime.Visible = false; textRetentionTimeWindow.Visible = false; } else { RetentionTime = explicitRetentionTime.RetentionTime; RetentionTimeWindow = explicitRetentionTime.RetentionTimeWindow; } if (!needOptionalValuesBox) { groupBoxOptionalValues.Visible = false; heightDelta = groupBoxOptionalValues.Height; } // Initialize label if (settings != null && defaultIsotopeLabelType != null) { _driverLabelType = new PeptideSettingsUI.LabelTypeComboDriver(PeptideSettingsUI.LabelTypeComboDriver.UsageType.InternalStandardPicker, comboIsotopeLabelType, settings.PeptideSettings.Modifications, null, null, null, null) { SelectedName = defaultIsotopeLabelType.Name }; } else { comboIsotopeLabelType.Visible = false; labelIsotopeLabelType.Visible = false; } Height -= heightDelta; }
public bool HasDigestion(PeptideSettings peptideSettings) { return(DigestionNames.Contains(peptideSettings.Enzyme.Name)); }
[MethodImpl(MethodImplOptions.NoOptimization)] // TODO(nicksh): reenable optimizations after we track down a NullReferenceException public static IList <ListViewItem> CreateListViewItems(IList <ProteinMatch> matches, String searchText, ProteinMatchTypes matchTypes, PeptideSettings peptideSettings, int maxCount) { var listItems = new SortedList <string, ListViewItem>(); var setUsedMatches = new HashSet <string>(); // First check for matching by sequence foreach (var match in matches) { if (matchTypes.Contains(ProteinMatchType.sequence)) { HashSet <String> addedPeptideSequences = new HashSet <string>(); FastaSequence fastaSequence; try { fastaSequence = new FastaSequence("name", "description", new ProteinMetadata[0], match.Protein.Sequence); // Not L10N } catch (InvalidDataException) { // It's possible that the peptide sequence in the fasta file was bogus, in which case we just don't digest it. continue; } foreach (Peptide peptide in peptideSettings.Enzyme.Digest(fastaSequence, peptideSettings.DigestSettings)) { if (!peptide.Sequence.StartsWith(searchText)) { continue; } if (!addedPeptideSequences.Add(peptide.Sequence)) { continue; } var listItem = new ListViewItem { Text = peptide.Sequence, Tag = new StatementCompletionItem { Peptide = peptide.Sequence, ProteinInfo = match.Protein.ProteinMetadata, SearchText = searchText }, }; StatementCompletionForm.AddDescription(listItem, match.Protein.ProteinMetadata.TextForMatchTypes(matchTypes), null); setUsedMatches.Add(match.Protein.Name); listItem.ImageIndex = (int)ImageId.peptide; var tooltip = new StringBuilder(); tooltip.AppendLine(Resources.StatementCompletionTextBox_CreateListViewItems_Descriptions) .Append(match.Protein.ProteinMetadata.TextForMatchTypes(matchTypes)); foreach (var name in match.Protein.AlternativeNames) { tooltip.AppendLine().Append(name.TextForMatchTypes(matchTypes)); } listItem.ToolTipText = StripTabs(tooltip.ToString()); // Note the leading space in this sort key - we'd like to list sequence matches first var key = TextUtil.SpaceSeparate(" ", listItem.Text, listItem.ToolTipText); // Not L10N if (!listItems.ContainsKey(key)) { listItems.Add(key, listItem); } } } } if (listItems.Count >= maxCount) { return(new List <ListViewItem>(listItems.Values)); // We used to exit here if we had any matches - but that's frustrating when you're not actually trying to match by sequence } // Decide which field not to display on righthand side, based on what's already showing on the left due to View|Targets|By* menu ProteinMatchTypes displayMatchTypes = ProteinMatchTypes.ALL; switch (SequenceTree.ProteinsDisplayMode) { case ProteinMetadataManager.ProteinDisplayMode.ByName: displayMatchTypes = displayMatchTypes.Except(ProteinMatchType.name); break; case ProteinMetadataManager.ProteinDisplayMode.ByAccession: displayMatchTypes = displayMatchTypes.Except(ProteinMatchType.accession); break; case ProteinMetadataManager.ProteinDisplayMode.ByGene: displayMatchTypes = displayMatchTypes.Except(ProteinMatchType.gene); break; case ProteinMetadataManager.ProteinDisplayMode.ByPreferredName: displayMatchTypes = displayMatchTypes.Except(ProteinMatchType.preferredName); break; } ProteinMatchTypes secondPassMatchTypes = matchTypes.Except( ProteinMatchType.sequence, // We already did sequence ProteinMatchType.description); // And aren't ready for description foreach (var match in matches) { if (setUsedMatches.Contains(match.Protein.Name)) { continue; } // Try matching on name, accession etc - cycle through name, accession, preferredName, gene foreach (ProteinMatchType tryType in secondPassMatchTypes) { if (match.MatchTypes.Contains(tryType)) { var listItem = new ListViewItem(); // Show description, and any other fields we were searching on if (match.AlternativeName != null) { listItem.Text = ProteinMetadataManager.ProteinModalDisplayText(match.AlternativeName, Settings.Default.ShowPeptidesDisplayMode); listItem.Tag = new StatementCompletionItem { ProteinInfo = match.AlternativeName, SearchText = searchText }; StatementCompletionForm.AddDescription(listItem, match.AlternativeName.TextForMatchTypes(displayMatchTypes.Except(ProteinMatchType.name)), searchText); } else { listItem.Text = ProteinMetadataManager.ProteinModalDisplayText(match.Protein.ProteinMetadata, Settings.Default.ShowPeptidesDisplayMode); listItem.Tag = new StatementCompletionItem { ProteinInfo = match.Protein.ProteinMetadata, SearchText = searchText }; StatementCompletionForm.AddDescription(listItem, match.Protein.ProteinMetadata.TextForMatchTypes(displayMatchTypes), searchText); } setUsedMatches.Add(match.Protein.Name); listItem.ImageIndex = (int)ImageId.protein; var tooltip = new StringBuilder(); tooltip.AppendLine(Resources.StatementCompletionTextBox_CreateListViewItems_Descriptions) .Append(match.Protein.ProteinMetadata.TextForMatchTypes(displayMatchTypes)); foreach (var altName in match.Protein.AlternativeNames) { tooltip.AppendLine().Append(altName.TextForMatchTypes(displayMatchTypes)); } listItem.ToolTipText = StripTabs(tooltip.ToString()); // We want the sort to be on the particular bit of metadata that we matched var key = TextUtil.SpaceSeparate(match.Protein.ProteinMetadata.TextForMatchTypes(ProteinMatchTypes.Singleton(tryType)), listItem.Text, listItem.ToolTipText); if (!listItems.ContainsKey(key)) { listItems.Add(key, listItem); } break; } } } if (listItems.Count >= maxCount) { return(new List <ListViewItem>(listItems.Values)); // We used to exit here if we had any matches - but that's frustrating when you're not actually trying to match by sequence } // Any matches by description? foreach (var match in matches) { if (setUsedMatches.Contains(match.Protein.Name)) { continue; } if (match.MatchTypes.Contains(ProteinMatchType.description)) { ProteinMetadata mainName = match.AlternativeDescription; string matchName = match.Protein.Name; var proteinInfo = match.Protein.ProteinMetadata; if (matchName != null && matchName.Length > MAX_NAME_LENGTH) { proteinInfo = proteinInfo.ChangeName(matchName.Substring(0, MAX_NAME_LENGTH) + "..."); // Not L10N } var alternativeNames = new List <ProteinMetadata>(); if (mainName == null) { mainName = proteinInfo; } else { alternativeNames.Add(proteinInfo); } var listItem = new ListViewItem { Text = ProteinMetadataManager.ProteinModalDisplayText(mainName, Settings.Default.ShowPeptidesDisplayMode), ImageIndex = (int)ImageId.protein, Tag = new StatementCompletionItem { ProteinInfo = proteinInfo, SearchText = searchText } }; StatementCompletionForm.AddDescription(listItem, mainName.TextForMatchTypes(displayMatchTypes), searchText); if (match.Protein.AlternativeNames.Count > 0) { alternativeNames.AddRange(match.Protein.AlternativeNames); StringBuilder tooltip = new StringBuilder(Resources.StatementCompletionTextBox_CreateListViewItems_Alternative_Names); foreach (var altName in alternativeNames) { if (altName.Name == mainName.Name) { continue; } tooltip.AppendLine().Append(altName.TextForMatchTypes(displayMatchTypes.Union(ProteinMatchType.name))); } listItem.ToolTipText = StripTabs(tooltip.ToString()); } // We want the sort to be on what we matched in the description, and what follows. var remains = match.Protein.ProteinMetadata.Description ?? string.Empty; int pos = remains.ToLower().IndexOf(searchText.ToLower(), StringComparison.Ordinal); if (pos > 0) { remains = remains.Substring(pos); } var key = TextUtil.SpaceSeparate(remains, listItem.Text, listItem.ToolTipText); if (!listItems.ContainsKey(key)) { listItems.Add(key, listItem); } } } return(new List <ListViewItem>(listItems.Values)); }
private BackgroundProteome Load(IDocumentContainer container, PeptideSettings settings, SrmDocument docCurrent, bool isBackgroundLoad) { // Only allow one background proteome to load at a time. This can // get tricky, if the user performs an undo and then a redo across // a change in background proteome. // Our only priority is accessing web services to add missing protein metadata. // There may also be a load initiation by the Peptide Settings dialog as foreground task, // it takes priority over the background task. lock (_lockLoadBackgroundProteome) { BackgroundProteome originalBackgroundProteome = settings.BackgroundProteome; BackgroundProteome validatedBackgroundProtome = originalBackgroundProteome.DatabaseValidated ? originalBackgroundProteome : new BackgroundProteome(originalBackgroundProteome.BackgroundProteomeSpec); if (IsNotLoadedExplained(settings, validatedBackgroundProtome, true) == null) { // protein metadata is resolved CompleteProcessing(container, validatedBackgroundProtome); Helpers.AssignIfEquals(ref validatedBackgroundProtome, originalBackgroundProteome); return(validatedBackgroundProtome); // No change needed } // we are here to resolve the protein metadata string name = originalBackgroundProteome.Name; IProgressStatus progressStatus = new ProgressStatus(string.Format(Resources.BackgroundProteomeManager_LoadBackground_Resolving_protein_details_for__0__proteome, name)); try { // The transaction commit for writing the digestion info can be very lengthy, avoid lock timeouts // by doing that work in a tempfile that no other thread knows aboout using (FileSaver fs = new FileSaver(originalBackgroundProteome.DatabasePath, StreamManager)) { File.Copy(originalBackgroundProteome.DatabasePath, fs.SafeName, true); var digestHelper = new DigestHelper(this, container, docCurrent, name, fs.SafeName, true); bool success = digestHelper.LookupProteinMetadata(ref progressStatus); if (digestHelper.IsCanceled || !success) { // Processing was canceled if (docCurrent != null) { EndProcessing(docCurrent); } UpdateProgress(progressStatus.Cancel()); return(null); } using (var proteomeDb = ProteomeDb.OpenProteomeDb(originalBackgroundProteome.DatabasePath)) { proteomeDb.DatabaseLock.AcquireWriterLock(int.MaxValue); // Wait for any existing readers to complete, prevent any new ones try { if (File.GetLastWriteTime(fs.RealName) <= File.GetLastWriteTime(fs.SafeName)) // Don't overwrite if foreground task has already updated { proteomeDb.CloseDbConnection(); // Get rid of any file handles if (!fs.Commit()) { if (docCurrent != null) { EndProcessing(docCurrent); } throw new IOException(string.Format(Resources.BackgroundProteomeManager_LoadBackground_Unable_to_rename_temporary_file_to__0__, fs.RealName)); } } } finally { proteomeDb.DatabaseLock.ReleaseWriterLock(); } } var updatedProteome = new BackgroundProteome(originalBackgroundProteome); using (var proteomeDb = originalBackgroundProteome.OpenProteomeDb()) { proteomeDb.AnalyzeDb(); // Now it's safe to start this potentially lengthy indexing operation } CompleteProcessing(container, updatedProteome); UpdateProgress(progressStatus.Complete()); return(updatedProteome); } } catch (Exception x) { var message = new StringBuilder(); message.AppendLine( string.Format(Resources.BackgroundProteomeManager_LoadBackground_Failed_updating_background_proteome__0__, name)); message.Append(x.Message); UpdateProgress(progressStatus.ChangeErrorException(new IOException(message.ToString(), x))); return(null); } } }
public Digestion GetDigestion(ProteomeDb proteomeDb, PeptideSettings peptideSettings) { return(proteomeDb.GetDigestion(peptideSettings.Enzyme.Name)); }
public Dictionary <Target, bool> PeptidesUniquenessFilter(Dictionary <Target, bool> sequences, PeptideSettings peptideSettings, SrmSettingsChangeMonitor progressMonitor) { var peptideUniquenessConstraint = peptideSettings.Filter.PeptideUniqueness; Assume.IsTrue(sequences.All(s => s.Value)); // Caller should seed this with all true if (peptideUniquenessConstraint == PeptideFilter.PeptideUniquenessConstraint.none || peptideSettings.BackgroundProteome == null || peptideSettings.BackgroundProteome.IsNone) { return(sequences); // No filtering } lock (_cache) { var peptideUniquenessDict = _cache.GetUniquenessDict(peptideSettings, sequences, progressMonitor); if (peptideUniquenessDict == null) { return(new Dictionary <Target, bool>()); // Cancelled } foreach (var seq in sequences.Keys.ToArray()) { DigestionPeptideStats appearances; if (peptideUniquenessDict.TryGetValue(seq, out appearances)) { bool isUnique; switch (peptideUniquenessConstraint) { case PeptideFilter.PeptideUniquenessConstraint.protein: isUnique = appearances.Proteins <= 1; break; case PeptideFilter.PeptideUniquenessConstraint.gene: isUnique = appearances.Genes <= 1; break; case PeptideFilter.PeptideUniquenessConstraint.species: isUnique = appearances.Species <= 1; break; default: throw new ArgumentOutOfRangeException(nameof(peptideSettings)); } sequences[seq] = isUnique; } } } return(sequences); }
public Digestion GetDigestion(ProteomeDb proteomeDb, PeptideSettings peptideSettings) { return(proteomeDb.GetDigestion()); }
public static ImportFastaSettings GetDefault(PeptideSettings peptideSettings) { return(new ImportFastaSettings(peptideSettings.Enzyme, peptideSettings.DigestSettings.MaxMissedCleavages, null, null, string.Empty, null, false)); }
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; } 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) { PeptideModifications modifications = new PeptideModifications( _peptideSettings.Modifications.StaticModifications, _peptideSettings.Modifications.MaxVariableMods, _peptideSettings.Modifications.MaxNeutralLosses, _driverLabelType.GetHeavyModifications(), // This is the only thing the user may have altered _peptideSettings.Modifications.InternalStandardTypes); var settings = _peptideSettings.ChangeModifications(modifications); // Only update if anything changed if (!Equals(settings, _peptideSettings)) { SrmSettings newSettings = _parent.DocumentUI.Settings.ChangePeptideSettings(settings); if (!_parent.ChangeSettings(newSettings, true)) { 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; }
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; }