public void Validate() { if (!string.IsNullOrEmpty(Formula)) { try { MonoisotopicMass = SequenceMassCalc.FormulaMass(BioMassCalc.MONOISOTOPIC, Formula); AverageMass = SequenceMassCalc.FormulaMass(BioMassCalc.AVERAGE, Formula); } catch (ArgumentException x) { throw new InvalidDataException(x.Message, x); // Pass original as inner exception } } if (AverageMass == 0 || MonoisotopicMass == 0) { throw new InvalidDataException(Resources.CustomMolecule_Validate_Custom_molecules_must_specify_a_formula_or_valid_monoisotopic_and_average_masses_); } if (AverageMass > MAX_MASS || MonoisotopicMass > MAX_MASS) { throw new InvalidDataException(string.Format(Resources.CustomMolecule_Validate_The_mass__0__of_the_custom_molecule_exceeeds_the_maximum_of__1__, AverageMass > MAX_MASS ? AverageMass : MonoisotopicMass, MAX_MASS)); } if (AverageMass < MIN_MASS || MonoisotopicMass < MIN_MASS) { throw new InvalidDataException(string.Format(Resources.CustomMolecule_Validate_The_mass__0__of_the_custom_molecule_is_less_than_the_minimum_of__1__, AverageMass < MIN_MASS ? AverageMass : MonoisotopicMass, MIN_MASS)); } }
public static Modification MakeModification(string unmodifiedSequence, ExplicitMod explicitMod) { var staticMod = explicitMod.Modification; int i = explicitMod.IndexAA; var monoMass = staticMod.MonoisotopicMass ?? SrmSettings.MonoisotopicMassCalc.GetAAModMass(unmodifiedSequence[i], i, unmodifiedSequence.Length); var avgMass = staticMod.AverageMass ?? SrmSettings.AverageMassCalc.GetAAModMass(unmodifiedSequence[i], i, unmodifiedSequence.Length); if (monoMass == 0 && avgMass == 0) { char aa = unmodifiedSequence[i]; if ((staticMod.LabelAtoms & LabelAtoms.LabelsAA) != LabelAtoms.None && AminoAcid.IsAA(aa)) { string heavyFormula = SequenceMassCalc.GetHeavyFormula(aa, staticMod.LabelAtoms); monoMass = SequenceMassCalc.FormulaMass(BioMassCalc.MONOISOTOPIC, heavyFormula, SequenceMassCalc.MassPrecision); avgMass = SequenceMassCalc.FormulaMass(BioMassCalc.AVERAGE, heavyFormula, SequenceMassCalc.MassPrecision); } } return(new Modification(explicitMod, monoMass, avgMass)); }
public static bool IsValidLibKey(string key) { try { SequenceMassCalc.FormulaMass(BioMassCalc.AVERAGE, key); } catch { return(false); } return(true); }
public void OkDialog() { var helper = new MessageBoxHelper(this); string name; if (!helper.ValidateNameTextBox(_editing ? (Control)textName : comboMod, out name)) { return; } // Allow updating the original modification if (!_editing || !Equals(name, Modification.Name)) { if (!ModNameAvailable(name)) { helper.ShowTextBoxError(_editing ? (Control)textName : comboMod, Resources.EditStaticModDlg_OkDialog_The_modification__0__already_exists, name); return; } } string aas = comboAA.Text; if (string.IsNullOrEmpty(aas)) { aas = null; } else { // Use the cleanest possible format. var sb = new StringBuilder(); foreach (string aaPart in aas.Split(SEPARATOR_AA)) { string aa = aaPart.Trim(); if (aa.Length == 0) { continue; } if (sb.Length > 0) { sb.Append(", "); // Not L10N } sb.Append(aa); } } string termString = comboTerm.SelectedItem.ToString(); ModTerminus?term = null; if (!string.IsNullOrEmpty(termString)) { term = (ModTerminus)Enum.Parse(typeof(ModTerminus), termString); } if (cbVariableMod.Checked && aas == null && term == null) { MessageDlg.Show(this, Resources.EditStaticModDlg_OkDialog_Variable_modifications_must_specify_amino_acid_or_terminus); comboAA.Focus(); return; } string formula = null; double? monoMass = null; double? avgMass = null; LabelAtoms labelAtoms = LabelAtoms.None; if (cbChemicalFormula.Checked) { formula = Formula; } else { labelAtoms = LabelAtoms; } // Get the losses to know whether any exist below IList <FragmentLoss> losses = null; if (listNeutralLosses.Items.Count > 0) { losses = Losses.ToArray(); } if (!string.IsNullOrEmpty(formula)) { try { SequenceMassCalc.FormulaMass(BioMassCalc.MONOISOTOPIC, formula, SequenceMassCalc.MassPrecision); } catch (ArgumentException x) { _formulaBox.ShowTextBoxErrorFormula(helper, x.Message); return; } } else if (labelAtoms == LabelAtoms.None) { formula = null; // Allow formula and both masses to be empty, if losses are present if (NotZero(_formulaBox.MonoMass) || NotZero(_formulaBox.AverageMass) || losses == null) { // TODO: Maximum and minimum masses should be formalized and applied everywhere double mass; if (!_formulaBox.ValidateMonoText(helper, -1500, 5000, out mass)) { return; } monoMass = mass; if (!_formulaBox.ValidateAverageText(helper, -1500, 5000, out mass)) { return; } avgMass = mass; } // Loss-only modifications may not be variable else if (cbVariableMod.Checked) { MessageDlg.Show(this, Resources.EditStaticModDlg_OkDialog_The_variable_checkbox_only_applies_to_precursor_modification_Product_ion_losses_are_inherently_variable); cbVariableMod.Focus(); return; } } else if (aas == null && term.HasValue) { MessageDlg.Show(this, Resources.EditStaticModDlg_OkDialog_Labeled_atoms_on_terminal_modification_are_not_valid); return; } RelativeRT relativeRT = RelativeRT.Matching; if (comboRelativeRT.Visible && comboRelativeRT.SelectedItem != null) { relativeRT = RelativeRTExtension.GetEnum(comboRelativeRT.SelectedItem.ToString()); } // Store state of the chemical formula checkbox for next use. if (cbChemicalFormula.Visible) { Settings.Default.ShowHeavyFormula = _formulaBox.FormulaVisible; } var newMod = new StaticMod(name, aas, term, cbVariableMod.Checked, formula, labelAtoms, relativeRT, monoMass, avgMass, losses); foreach (StaticMod mod in _existing) { if (newMod.Equivalent(mod) && !(_editing && mod.Equals(_originalModification))) { if (DialogResult.OK == MultiButtonMsgDlg.Show( this, TextUtil.LineSeparate(Resources.EditStaticModDlg_OkDialog_There_is_an_existing_modification_with_the_same_settings, string.Format("'{0}'.", mod.Name), // Not L10N string.Empty, Resources.EditStaticModDlg_OkDialog_Continue), MultiButtonMsgDlg.BUTTON_OK)) { Modification = newMod; DialogResult = DialogResult.OK; } return; } } var uniMod = UniMod.GetModification(name, IsStructural); // If the modification name is not found in Unimod, check if there exists a modification in Unimod that matches // the dialog modification, and prompt the user to to use the Unimod modification instead. if (uniMod == null) { var matchingMod = UniMod.FindMatchingStaticMod(newMod, IsStructural); if (matchingMod != null && (ModNameAvailable(matchingMod.Name) || (_editing && Equals(matchingMod.Name, Modification.Name)))) { var result = MultiButtonMsgDlg.Show( this, TextUtil.LineSeparate(Resources.EditStaticModDlg_OkDialog_There_is_a_Unimod_modification_with_the_same_settings, string.Empty, string.Format(Resources.EditStaticModDlg_OkDialog_Click__Unimod__to_use_the_name___0___, matchingMod.Name), string.Format(Resources.EditStaticModDlg_OkDialog_Click__Custom__to_use_the_name___0___, name)), Resources.EditStaticModDlg_OkDialog_Unimod, Resources.EditStaticModDlg_OkDialog_Custom, true); if (result == DialogResult.Yes) { newMod = matchingMod.MatchVariableAndLossInclusion(newMod); // Unimod } if (result == DialogResult.Cancel) { return; } } } else { // If the dialog modification matches the modification of the same name in Unimod, // use the UnimodId. if (newMod.Equivalent(uniMod)) { newMod = uniMod.MatchVariableAndLossInclusion(newMod); } else { // Finally, if the modification name is found in Unimod, but the modification in Unimod does not // match the dialog modification, prompt the user to use the Unimod modification definition instead. if (DialogResult.OK != MultiButtonMsgDlg.Show( this, TextUtil.LineSeparate(string.Format(Resources.EditStaticModDlg_OkDialog_This_modification_does_not_match_the_Unimod_specifications_for___0___, name), string.Empty, Resources.EditStaticModDlg_OkDialog_Use_non_standard_settings_for_this_name), MultiButtonMsgDlg.BUTTON_OK)) { return; } } } _modification = newMod; DialogResult = DialogResult.OK; }
private MeasuredIon ValidateCustomIon(string name) { var helper = new MessageBoxHelper(this); string formula = (_formulaBox.NeutralFormula ?? string.Empty).ToString(LocalizationHelper.CurrentCulture); var charge = ValidateCharge(); if (!charge.HasValue) { return(null); } double monoMass; double avgMass; if (!string.IsNullOrEmpty(formula)) { // Mass is specified by chemical formula try { monoMass = SequenceMassCalc.FormulaMass(BioMassCalc.MONOISOTOPIC, formula, SequenceMassCalc.MassPrecision); avgMass = SequenceMassCalc.FormulaMass(BioMassCalc.AVERAGE, formula, SequenceMassCalc.MassPrecision); } catch (ArgumentException x) { helper.ShowTextBoxError(_formulaBox, x.Message); return(null); } } else if (_formulaBox.MonoMass != null || _formulaBox.AverageMass != null) { // Mass is specified by combination of mz and charge formula = null; if (!_formulaBox.ValidateMonoText(helper)) { return(null); } if (!_formulaBox.ValidateAverageText(helper)) { return(null); } // CONSIDER(bspratt): should we switch to using adducts instead of baking ions into formula? _formulaBox.Adduct = Adduct.FromChargeNoMass(charge.Value); // This provokes calculation of mass from displayed mz values monoMass = _formulaBox.MonoMass.Value; avgMass = _formulaBox.AverageMass.Value; } else { // User hasn't fully specified either way _formulaBox.ShowTextBoxErrorFormula(helper, Resources.EditMeasuredIonDlg_OkDialog_Please_specify_a_formula_or_constant_masses); return(null); } if (MeasuredIon.MIN_REPORTER_MASS > monoMass || MeasuredIon.MIN_REPORTER_MASS > avgMass) { _formulaBox.ShowTextBoxErrorMonoMass(helper, string.Format(Resources.EditMeasuredIonDlg_OkDialog_Reporter_ion_masses_must_be_less_than_or_equal_to__0__, MeasuredIon.MAX_REPORTER_MASS)); return(null); } if (monoMass > MeasuredIon.MAX_REPORTER_MASS || avgMass > MeasuredIon.MAX_REPORTER_MASS) { _formulaBox.ShowTextBoxErrorAverageMass(helper, string.Format(Resources.EditMeasuredIonDlg_OkDialog_Reporter_ion_masses_must_be_less_than_or_equal_to__0__, MeasuredIon.MAX_REPORTER_MASS)); return(null); } return(new MeasuredIon(name, formula, monoMass, avgMass, Adduct.FromChargeNoMass(charge.Value))); // Charge-only adduct: user is assumed to have placed ion elements in formula }
public void TestUniMod() { // UpdateTestXML is used to update the test files if the modifications in UniMod.cs // have changed. Before UpdateTestXML is called, TestUniMod should pass with the new changes // to make sure we haven't lost/broken any modifications from earlier versions of UniMod.cs. // Note: The test will always run against the last build XML. Run twice when updating. UpdateTestXML(); foreach (StaticMod mod in UniMod.DictUniModIds.Values) { // UniModCompiler should not set the masses. if (mod.Formula == null) { Assert.IsNull(mod.MonoisotopicMass); Assert.IsNull(mod.AverageMass); } else { Assert.AreEqual(mod.MonoisotopicMass, SequenceMassCalc.FormulaMass(BioMassCalc.MONOISOTOPIC, mod.Formula, SequenceMassCalc.MassPrecision)); Assert.AreEqual(mod.AverageMass, SequenceMassCalc.FormulaMass(BioMassCalc.AVERAGE, mod.Formula, SequenceMassCalc.MassPrecision)); } // Everything amino acid/terminus that is part of the modification should be present in // the name of the modification. var aasAndTermInName = mod.Name.Split(new[] { ' ' }, 2)[1]; if (mod.Terminus != null) { Assert.IsTrue(aasAndTermInName.Contains(mod.Terminus.Value.ToString())); } if (mod.AAs != null) { foreach (char aa in mod.AminoAcids) { Assert.IsTrue(aasAndTermInName.Contains(aa)); } } // Should not have label atoms if no amino acids are listed. if (!Equals(mod.LabelAtoms, LabelAtoms.None)) { Assert.IsTrue(mod.AAs != null); } } // Testing ValidateID. var phospho = UniMod.DictStructuralModNames["Phospho (ST)"]; Assert.IsTrue(UniMod.ValidateID(phospho.ChangeExplicit(true))); Assert.IsTrue(UniMod.ValidateID(phospho.ChangeVariable(true))); Assert.IsFalse(UniMod.ValidateID((StaticMod)phospho.ChangeName("Phospho"))); StreamReader staticReader = new StreamReader(GetTestStream(STATIC_LIST_FILE)); string staticMods = staticReader.ReadToEnd(); staticReader.Close(); AssertEx.DeserializeNoError <StaticModList>(staticMods, false); StreamReader heavyReader = new StreamReader(GetTestStream(HEAVY_LIST_FILE)); string heavyMods = heavyReader.ReadToEnd(); heavyReader.Close(); AssertEx.DeserializeNoError <HeavyModList>(heavyMods, false); }
private void UpdateAverageAndMonoTextsForFormula() { bool valid; try { var formula = Formula; // Get current formula and adduct var userinput = textFormula.Text.Trim(); if (_editMode == EditMode.adduct_only) { if (!string.IsNullOrEmpty(userinput) && !userinput.StartsWith(@"[")) { // Assume they're trying to type an adduct userinput = @"[" + userinput + @"]"; } if (string.IsNullOrEmpty(NeutralFormula)) { formula = null; // Parent molecule was described as mass only } else { formula = NeutralFormula + userinput; // Try to apply this new adduct to parent molecule } } else { formula = userinput; } string neutralFormula; Molecule ion; Adduct adduct; if (!IonInfo.IsFormulaWithAdduct(formula, out ion, out adduct, out neutralFormula)) { neutralFormula = formula; if (!Adduct.TryParse(userinput, out adduct)) { adduct = Adduct.EMPTY; } } if (_editMode != EditMode.adduct_only) { NeutralFormula = neutralFormula; } if (_editMode != EditMode.formula_only) { Adduct = adduct; } // Update mass/mz displays if (string.IsNullOrEmpty(neutralFormula)) { if (!adduct.IsEmpty) { // No formula, but adduct changed Adduct = adduct; // ReSharper disable once PossibleNullReferenceException GetTextFromMass(_neutralMonoMass, MassType.Monoisotopic); // Just to see if it throws or not GetTextFromMass(_neutralAverageMass, MassType.Average); // Just to see if it throws or not } } else { // Is there an isotopic label we should apply to get the mass? if (IsotopeLabelsForMassCalc != null && (Adduct.IsEmpty || !Adduct.HasIsotopeLabels)) // If adduct declares an isotope, that takes precedence { neutralFormula = IsotopeLabelsForMassCalc.Aggregate(neutralFormula, (current, kvp) => current.Replace(kvp.Key, kvp.Value)); } var monoMass = SequenceMassCalc.FormulaMass(BioMassCalc.MONOISOTOPIC, neutralFormula, SequenceMassCalc.MassPrecision); var averageMass = SequenceMassCalc.FormulaMass(BioMassCalc.AVERAGE, neutralFormula, SequenceMassCalc.MassPrecision); GetTextFromMass(monoMass, MassType.Monoisotopic); // Just to see if it throws or not GetTextFromMass(averageMass, MassType.Average); // Just to see if it throws or not MonoMass = monoMass; AverageMass = averageMass; } valid = true; // If we got here, formula parsed OK, or adduct did textFormula.ForeColor = Color.Black; if (_editMode == EditMode.adduct_only) { textFormula.Text = userinput; // Enforce proper adduct formatting if (adduct.IsEmpty) { valid = false; // Adduct did not parse } } else if (_editMode == EditMode.formula_only) { valid &= adduct.IsEmpty; // Should not have anything going on with adduct here } } catch (InvalidOperationException) { valid = false; } catch (ArgumentException) { valid = false; } if (valid) { textFormula.ForeColor = Color.Black; } else { textFormula.ForeColor = Color.Red; textMono.Text = textAverage.Text = string.Empty; } // Allow direct editing of masses if direct editing of formula is allowed, but formula is empty MassEnabled = _editMode != EditMode.adduct_only && string.IsNullOrEmpty(_neutralFormula); }
public void OkDialog() { var helper = new MessageBoxHelper(this); string formulaLoss = _formulaBox.Formula; double?monoLoss = null; double?avgLoss = null; if (!string.IsNullOrEmpty(formulaLoss)) { try { double massMono = SequenceMassCalc.FormulaMass(BioMassCalc.MONOISOTOPIC, formulaLoss, SequenceMassCalc.MassPrecision); double massAverage = SequenceMassCalc.FormulaMass(BioMassCalc.AVERAGE, formulaLoss, SequenceMassCalc.MassPrecision); if (FragmentLoss.MIN_LOSS_MASS > massMono || FragmentLoss.MIN_LOSS_MASS > massAverage) { _formulaBox.ShowTextBoxErrorFormula(helper, string.Format(Resources.EditFragmentLossDlg_OkDialog_Neutral_loss_masses_must_be_greater_than_or_equal_to__0__, FragmentLoss.MIN_LOSS_MASS)); return; } if (massMono > FragmentLoss.MAX_LOSS_MASS || massAverage > FragmentLoss.MAX_LOSS_MASS) { _formulaBox.ShowTextBoxErrorFormula(helper, string.Format(Resources.EditFragmentLossDlg_OkDialog_Neutral_loss_masses_must_be_less_than_or_equal_to__0__, FragmentLoss.MAX_LOSS_MASS)); return; } } catch (ArgumentException x) { _formulaBox.ShowTextBoxErrorFormula(helper, x.Message); return; } } else if (_formulaBox.MonoMass != null || _formulaBox.AverageMass != null) { formulaLoss = null; double mass; if (!_formulaBox.ValidateMonoText(helper, FragmentLoss.MIN_LOSS_MASS, FragmentLoss.MAX_LOSS_MASS, out mass)) { return; } monoLoss = mass; if (!_formulaBox.ValidateAverageText(helper, FragmentLoss.MIN_LOSS_MASS, FragmentLoss.MAX_LOSS_MASS, out mass)) { return; } avgLoss = mass; } else { _formulaBox.ShowTextBoxErrorFormula(helper, Resources.EditFragmentLossDlg_OkDialog_Please_specify_a_formula_or_constant_masses); return; } // Make sure the new loss does not already exist. var loss = new FragmentLoss(formulaLoss, monoLoss, avgLoss, Inclusion); if (_existing.Contains(loss)) { MessageDlg.Show(this, string.Format(Resources.EditFragmentLossDlg_OkDialog_The_loss__0__already_exists, loss)); return; } Loss = loss; DialogResult = DialogResult.OK; }
public const string UnimodPrefix = "unimod:"; // Not L10N /// <summary> /// Constructs a ModifiedSequence from SrmSettings and PeptideDocNode. /// </summary> public static ModifiedSequence GetModifiedSequence(SrmSettings settings, PeptideDocNode docNode, IsotopeLabelType labelType) { if (docNode.Peptide.IsCustomMolecule) { return(null); } var unmodifiedSequence = docNode.Peptide.Sequence; bool includeStaticMods = true; bool includeStaticHeavyMods = false; List <Modification> explicitMods = new List <Modification>(); if (null != docNode.ExplicitMods) { var staticBaseMods = docNode.ExplicitMods.GetStaticBaseMods(labelType); var labelMods = docNode.ExplicitMods.GetModifications(labelType); var explicitLabelType = labelType; if (labelMods == null && !labelType.IsLight) { labelMods = docNode.ExplicitMods.GetModifications(IsotopeLabelType.light); explicitLabelType = IsotopeLabelType.light; includeStaticHeavyMods = true; } if (labelMods != null || staticBaseMods != null) { IEnumerable <ExplicitMod> modsToAdd = (labelMods ?? Enumerable.Empty <ExplicitMod>()) .Concat(staticBaseMods ?? Enumerable.Empty <ExplicitMod>()); var monoMasses = docNode.ExplicitMods.GetModMasses(MassType.Monoisotopic, explicitLabelType); var avgMasses = docNode.ExplicitMods.GetModMasses(MassType.Average, explicitLabelType); foreach (var mod in modsToAdd) { explicitMods.Add(new Modification(mod, monoMasses[mod.IndexAA], avgMasses[mod.IndexAA])); } includeStaticMods = docNode.ExplicitMods.IsVariableStaticMods && staticBaseMods == null; } } if (includeStaticMods || includeStaticHeavyMods) { var peptideModifications = settings.PeptideSettings.Modifications; for (int i = 0; i < unmodifiedSequence.Length; i++) { IEnumerable <StaticMod> staticMods = peptideModifications.GetModifications(labelType); if (!labelType.IsLight && includeStaticMods) { staticMods = peptideModifications.GetModifications(IsotopeLabelType.light).Concat(staticMods); } foreach (var staticMod in staticMods) { if (staticMod.IsExplicit || staticMod.IsVariable) { continue; } if (staticMod.Terminus.HasValue) { if (staticMod.Terminus == ModTerminus.N && i != 0) { continue; } if (staticMod.Terminus == ModTerminus.C && i != unmodifiedSequence.Length - 1) { continue; } } if (!string.IsNullOrEmpty(staticMod.AAs) && !staticMod.AAs.Contains(unmodifiedSequence[i])) { continue; } var monoMass = staticMod.MonoisotopicMass ?? SrmSettings.MonoisotopicMassCalc.GetAAModMass(unmodifiedSequence[i], i, unmodifiedSequence.Length); var avgMass = staticMod.AverageMass ?? SrmSettings.AverageMassCalc.GetAAModMass(unmodifiedSequence[i], i, unmodifiedSequence.Length); if (monoMass == 0 && avgMass == 0) { char aa = unmodifiedSequence[i]; if ((staticMod.LabelAtoms & LabelAtoms.LabelsAA) != LabelAtoms.None && AminoAcid.IsAA(aa)) { string heavyFormula = SequenceMassCalc.GetHeavyFormula(aa, staticMod.LabelAtoms); monoMass = SequenceMassCalc.FormulaMass(BioMassCalc.MONOISOTOPIC, heavyFormula, SequenceMassCalc.MassPrecision); avgMass = SequenceMassCalc.FormulaMass(BioMassCalc.AVERAGE, heavyFormula, SequenceMassCalc.MassPrecision); } } explicitMods.Add(new Modification(new ExplicitMod(i, staticMod), monoMass, avgMass)); } } } return(new ModifiedSequence(unmodifiedSequence, explicitMods, settings.TransitionSettings.Prediction.PrecursorMassType)); }