/// <summary> /// Completely removes a particular isotope from this chemical formula. /// </summary> /// <param name="isotope">The isotope to remove</param> /// <returns>True if the isotope was in the chemical formula and removed, false otherwise</returns> public int Remove(Isotope isotope) { if (isotope == null) { return(0); } int id = isotope.UniqueId; int count; if (id > _largestIsotopeId || (count = _isotopes[id]) == 0) { // isotope not contained or is already zero, do nothing and just return false return(0); } MonoisotopicMass -= isotope.AtomicMass * count; _isotopes[id] = 0; if (id == _largestIsotopeId) { // id is the largest, find the new largest FindLargestIsotope(); } _isFormulaDirty = _isDirty = true; return(count); }
/// <summary> /// Return the number of given isotopes in this chemical fomrula /// </summary> /// <param name="isotope"></param> /// <returns></returns> public int Count(Isotope isotope) { if (isotope == null || isotope.UniqueId > _largestIsotopeId) { return(0); } return(_isotopes[isotope.UniqueId]); }
public static IEnumerable <IChemicalFormula> Validate(this IEnumerable <IChemicalFormula> formulas, FilterTypes filters = FilterTypes.All) { bool useValence = filters.HasFlag(FilterTypes.Valence); bool useHydrogenCarbonRatio = filters.HasFlag(FilterTypes.HydrogenCarbonRatio); foreach (IChemicalFormula formula in formulas) { if (useHydrogenCarbonRatio) { double ratio = formula.ChemicalFormula.GetCarbonHydrogenRatio(); if (ratio < 0.5 || ratio > 2.0) { continue; } } if (useValence) { int totalValence = 0; int maxValence = 0; int oddValences = 0; int atomCount = 0; int[] isotopes = formula.ChemicalFormula.GetIsotopes(); for (int i = 0; i < isotopes.Length; i++) { int numAtoms = isotopes[i]; if (numAtoms != 0) { continue; } Isotope isotope = PeriodicTable.GetIsotope(i); int numValenceElectrons = isotope.ValenceElectrons; totalValence += numValenceElectrons * numAtoms; atomCount += numAtoms; if (numValenceElectrons > maxValence) { maxValence = numValenceElectrons; } if (numValenceElectrons % 2 != 0) { oddValences += numAtoms; } } if (!((totalValence % 2 == 0 || oddValences % 2 == 0) && (totalValence >= 2 * maxValence) && (totalValence >= ((2 * atomCount) - 1)))) { continue; } } yield return(formula); } }
/// <summary> /// Add the principal isotope of the element to this chemical formula /// given its chemical symbol /// </summary> /// <param name="symbol">The chemical symbol of the element to add</param> /// <param name="count">The number of the element to add</param> public void Add(string symbol, int count) { try { Isotope isotope = PeriodicTable.GetElement(symbol).PrincipalIsotope; Add(isotope, count); } catch (KeyNotFoundException e) { throw new KeyNotFoundException(string.Format("The element symbol '{0}' is not found in the periodic table", symbol), e); } }
/// <summary> /// Parses a string representation of chemical formula and adds the elements /// to this chemical formula /// </summary> /// <param name="formula">the Chemical Formula to parse</param> private void ParseString(string formula) { if (string.IsNullOrEmpty(formula)) { return; } if (!IsValidChemicalFormula(formula)) { throw new FormatException("Input string for chemical formula was in an incorrect format"); } foreach (Match match in FormulaRegex.Matches(formula)) { string chemsym = match.Groups[1].Value; // Group 1: Chemical Symbol Element element; if (PeriodicTable.TryGetElement(chemsym, out element)) { Isotope isotope = element.PrincipalIsotope; // Start with the most abundant (principal) isotope if (chemsym.Equals("D")) // Special case for Deuterium { isotope = element.Isotopes[2]; } else if (match.Groups[2].Success) // Group 2 (optional): Isotope Mass Number { isotope = element[int.Parse(match.Groups[2].Value)]; } int sign = match.Groups[3].Success ? // Group 3 (optional): Negative Sign -1 : 1; int numofelem = match.Groups[4].Success ? // Group 4 (optional): Number of Elements int.Parse(match.Groups[4].Value) : 1; Add(isotope, sign * numofelem); } else { throw new ArgumentException(string.Format("The chemical Symbol '{0}' does not exist in the Periodic Table", chemsym)); } } }
/// <summary> /// Recalculate parameters of the chemical formula /// </summary> private void CleanUp() { int atomCount = 0; int isotopeCount = 0; double monoMass = 0.0; double avgMass = 0.0; HashSet <int> elements = new HashSet <int>(); // Loop over every possible isotope in this formula for (int i = 0; i <= _largestIsotopeId; i++) { int count = _isotopes[i]; // Skip zero isotopes if (count == 0) { continue; } Isotope isotope = PeriodicTable.GetIsotope(i); Element element = isotope.Element; elements.Add(element.AtomicNumber); isotopeCount++; atomCount += count; monoMass += count * isotope.AtomicMass; avgMass += count * element.AverageMass; } // Set the instance variables to their new values _elementCount = elements.Count; MonoisotopicMass = monoMass; _averageMass = avgMass; _isotopeCount = isotopeCount; _atomCount = atomCount; // Mark as clean _isDirty = false; }
/// <summary> /// Add an isotope to this chemical formula /// </summary> /// <param name="isotope">The isotope to add</param> /// <param name="count">The number of the isotope to add</param> public void Add(Isotope isotope, int count) { if (isotope == null || count == 0) { return; } MonoisotopicMass += isotope.AtomicMass * count; _isFormulaDirty = _isDirty = true; int id = isotope.UniqueId; if (id > _largestIsotopeId) { // Isotope doesn't exist, set the count (faster than the += below) _largestIsotopeId = id; if (id >= _isotopes.Length) { // resize array if it is too small Array.Resize(ref _isotopes, id + 1); } _isotopes[id] = count; return; } _isotopes[id] += count; // Force update of the largest isotope // if the largest isotope got cleared if (_isotopes[_largestIsotopeId] == 0) { FindLargestIsotope(); } }
/// <summary> /// Add an isotope to this element /// </summary> /// <param name="atomicNumber">The atomic number of the isotope</param> /// <param name="atomicMass">The atomic mass of the isotope </param> /// <param name="abundance">The natural relative abundance of the isotope</param> /// <returns>The created isotopes that is added to this element</returns> internal Isotope AddIsotope(int atomicNumber, double atomicMass, float abundance) { var isotope = new Isotope(this, atomicNumber, atomicMass, abundance); if (Isotopes.ContainsKey(atomicNumber)) { return(isotope); } Isotopes.Add(atomicNumber, isotope); TotalAbundance += abundance; _totalMass += abundance * atomicMass; AverageMass = _totalMass / TotalAbundance; if (PrincipalIsotope != null && !(abundance > PrincipalIsotope.RelativeAbundance)) { return(isotope); } if (PrincipalIsotope != null) { PrincipalIsotope.IsPrincipalIsotope = false; } PrincipalIsotope = isotope; PrincipalIsotope.IsPrincipalIsotope = true; return(isotope); }
/// <summary> /// Replaces one isotope with another. /// Replacement happens on a 1 to 1 basis, i.e., if you remove 5 you will add 5 /// </summary> /// <param name="isotopeToRemove">The isotope to remove</param> /// <param name="isotopToAdd">The isotope to add</param> public void Replace(Isotope isotopeToRemove, Isotope isotopToAdd) { int numberRemoved = Remove(isotopeToRemove); Add(isotopToAdd, numberRemoved); }
public void AddConstraint(Isotope isotope, Range <int> range) { AddConstraint(isotope, range.Minimum, range.Maximum); }
public void RemoveConstraint(Isotope isotope) { MinimumFormula.Remove(isotope); MaximumFormula.Remove(isotope); }
/// <summary> /// Load a xml file containing elemental and isotopic data into the periodic table /// </summary> public static void Load(string filePath) { _elements.Clear(); Element element = null; _isotopes = new Isotope[500]; BiggestIsotopeNumber = -1; using (XmlReader reader = XmlReader.Create(filePath)) { while (reader.Read()) { if (!reader.IsStartElement()) { continue; } switch (reader.Name) { case "Element": string name = reader["Name"]; string symbol = reader["Symbol"]; int atomicnumber = int.Parse(reader["AtomicNumber"]); int valenceElectrons = int.Parse(reader["ValenceElectrons"]); element = new Element(name, symbol, atomicnumber, valenceElectrons); AddElement(element); break; case "Isotope": string unqiueId = reader["Id"]; string a = reader["Mass"]; double mass = double.Parse(reader["Mass"], CultureInfo.CurrentCulture); int massNumber = int.Parse(reader["MassNumber"]); float abundance = float.Parse(reader["Abundance"], CultureInfo.CurrentCulture); if (abundance > 0 && element != null) { Isotope isotope = element.AddIsotope(massNumber, mass, abundance); if (unqiueId != null) { int uniqueId = int.Parse(unqiueId); if (uniqueId > BiggestIsotopeNumber) { BiggestIsotopeNumber = uniqueId; } isotope.UniqueId = uniqueId; _isotopes[uniqueId] = isotope; } else { isotope.UniqueId = BiggestIsotopeNumber; _isotopes[BiggestIsotopeNumber++] = isotope; } } break; } } } if (_isotopes.Length > BiggestIsotopeNumber) { Array.Resize(ref _isotopes, BiggestIsotopeNumber + 1); } }
/// <summary> /// Add an isotope to this element /// </summary> /// <param name="atomicNumber">The atomic number of the isotope</param> /// <param name="atomicMass">The atomic mass of the isotope </param> /// <param name="abundance">The natural relative abundance of the isotope</param> /// <returns>The created isotopes that is added to this element</returns> internal Isotope AddIsotope(int atomicNumber, double atomicMass, float abundance) { var isotope = new Isotope(this, atomicNumber, atomicMass, abundance); if (!Isotopes.ContainsKey(atomicNumber)) { Isotopes.Add(atomicNumber, isotope); TotalAbundance += abundance; _totalMass += abundance * atomicMass; AverageMass = _totalMass / TotalAbundance; if (PrincipalIsotope == null || abundance > PrincipalIsotope.RelativeAbundance) { if (PrincipalIsotope != null) { PrincipalIsotope.IsPrincipalIsotope = false; } PrincipalIsotope = isotope; PrincipalIsotope.IsPrincipalIsotope = true; } } return isotope; }
public void AddConstraint(Isotope isotope, int min, int max) { MinimumFormula.Add(isotope, min); MaximumFormula.Add(isotope, max); }
/// <summary> /// Remove a isotope from this chemical formula /// </summary> /// <param name="isotope">The isotope to remove</param> /// <param name="count">The number of isotopes to remove</param> public void Remove(Isotope isotope, int count) { Add(isotope, -count); }
public void RemoveConstraint(Isotope isotope) { _minFormula.Remove(isotope); _maxFormula.Remove(isotope); }
/// <summary> /// Checks if the isotope is present in this chemical formula /// </summary> /// <param name="isotope">The isotope to look for</param> /// <returns>True if there is a non-negative number of the isotope in this formula</returns> public bool Contains(Isotope isotope) { return(Count(isotope) != 0); }
public void AddConstraint(Isotope isotope, int min, int max) { _minFormula.Add(isotope, min); _maxFormula.Add(isotope, max); }
public int Count(string symbol, int atomicNumber) { Isotope isotope = PeriodicTable.GetElement(symbol)[atomicNumber]; return(Count(isotope)); }
public void AddConstraint(Isotope isotope, Range<int> range) { AddConstraint(isotope, range.Minimum, range.Maximum); }
/// <summary> /// Produces the Hill Notation of the chemical formula /// </summary> public string GetHillNotation(string delimiter = "") { string carbonPart = string.Empty; string hydrogenPart = string.Empty; List <string> otherParts = new List <string>(); StringBuilder sb = new StringBuilder(4); bool nonNullDelimiter = !string.IsNullOrEmpty(delimiter); for (int i = 0; i <= _largestIsotopeId; i++) { int count = _isotopes[i]; if (count == 0) { continue; } Isotope isotope = PeriodicTable.GetIsotope(i); sb.Clear(); sb.Append(isotope.AtomicSymbol); if (!isotope.IsPrincipalIsotope) { sb.Append('{'); sb.Append(isotope.MassNumber); sb.Append('}'); } if (count != 1) { sb.Append(count); } switch (isotope.AtomicSymbol) { case "C": if (nonNullDelimiter && !string.IsNullOrEmpty(carbonPart)) { carbonPart += delimiter; } carbonPart += sb.ToString(); break; case "D": case "H": if (nonNullDelimiter && !string.IsNullOrEmpty(hydrogenPart)) { hydrogenPart += delimiter; } hydrogenPart += sb.ToString(); break; default: otherParts.Add(sb.ToString()); break; } } if (string.IsNullOrEmpty(carbonPart)) { // No carbons, so just add the hydrogen to the list and sort alphabetically if (!string.IsNullOrEmpty(hydrogenPart)) { otherParts.Add(hydrogenPart); } otherParts.Sort(); } else { otherParts.Sort(); if (!string.IsNullOrEmpty(hydrogenPart)) { otherParts.Insert(0, hydrogenPart); } otherParts.Insert(0, carbonPart); } return(string.Join(delimiter, otherParts)); }