The Periodic Table of Elements.
Ejemplo n.º 1
0
        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);
            }
        }
Ejemplo n.º 2
0
 /// <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);
     }
 }
Ejemplo n.º 3
0
        /// <summary>
        /// Gets the unique elements in this chemical formula
        /// </summary>
        /// <returns></returns>
        public IEnumerable <Element> GetElements()
        {
            HashSet <Element> elements = new HashSet <Element>();

            for (int i = 0; i <= _largestIsotopeId; i++)
            {
                if (_isotopes[i] != 0)
                {
                    elements.Add(PeriodicTable.GetIsotope(i).Element);
                }
            }
            return(elements);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Gets the total number of protons in this chemical formula
        /// </summary>
        /// <returns></returns>
        public int GetProtonCount()
        {
            int protons = 0;

            for (int i = 0; i <= _largestIsotopeId; i++)
            {
                if (_isotopes[i] == 0)
                {
                    continue;
                }

                protons += PeriodicTable.GetIsotope(i).Protons *_isotopes[i];
            }
            return(protons);
        }
Ejemplo n.º 5
0
        /// <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));
                }
            }
        }
Ejemplo n.º 6
0
        public ChemicalFormula(int[] uniqueIdCounts)
        {
            int count = uniqueIdCounts.Length;

            _isotopes        = new int[count];
            MonoisotopicMass = 0;
            for (int i = 0; i < count; i++)
            {
                int isotopes = uniqueIdCounts[i];
                if (isotopes != 0)
                {
                    _isotopes[i]      = isotopes;
                    MonoisotopicMass += isotopes * PeriodicTable.GetIsotope(i).AtomicMass;
                    _largestIsotopeId = i;
                }
            }
            _isFormulaDirty = _isDirty = true;
        }
Ejemplo n.º 7
0
        /// <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;
        }
Ejemplo n.º 8
0
        /// <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));
        }
Ejemplo n.º 9
0
        public int Count(string symbol, int atomicNumber)
        {
            Isotope isotope = PeriodicTable.GetElement(symbol)[atomicNumber];

            return(Count(isotope));
        }
Ejemplo n.º 10
0
        public int Count(string symbol)
        {
            Element element = PeriodicTable.GetElement(symbol);

            return(Count(element));
        }
Ejemplo n.º 11
0
 /// <summary>
 /// Remove all the isotopes of an chemical element represented by the symbol
 /// from this chemical formula
 /// </summary>
 /// <param name="symbol">The symbol of the chemical element to remove</param>
 /// <returns>True if the element was present and removed, false otherwise</returns>
 public int Remove(string symbol)
 {
     return(Remove(PeriodicTable.GetElement(symbol)));
 }
Ejemplo n.º 12
0
 /// <summary>
 /// Remove the principal isotope of the element represented by the symbol
 /// from this chemical formula
 /// </summary>
 /// <param name="symbol">The symbol of the chemical element to remove</param>
 /// <param name="count">The number of isotopes to remove</param>
 public void Remove(string symbol, int count)
 {
     Add(PeriodicTable.GetElement(symbol).PrincipalIsotope, -count);
 }
Ejemplo n.º 13
0
        public IEnumerable <ChemicalFormula> FromMass(double lowMass, double highMass, int maxNumberOfResults = int.MaxValue, bool sort = true)
        {
            if (highMass <= lowMass)
            {
                throw new ArgumentException("The high mass must be greater than the low mass");
            }

            if (!MaximumFormula.Contains(MinimumFormula))
            {
                throw new ArgumentException("The maximum formula must include the minimum formula");
            }

            List <ChemicalFormula> returnFormulas = new List <ChemicalFormula>();

            // The minimum formula required for any return formulas

            double correctedLowMass  = lowMass;
            double correctedHighMass = highMass;

            bool minFormulaExists = MinimumFormula.IsotopeCount != 0;

            int[]  minValues      = null;
            double minFormulaMass = 0;

            if (minFormulaExists)
            {
                minValues      = MinimumFormula.GetIsotopes();
                minFormulaMass = MinimumFormula.MonoisotopicMass;

                correctedLowMass  -= minFormulaMass;
                correctedHighMass -= minFormulaMass;

                // Add the minimum formula itself if it is within the bounds
            }

            // The maximum formula allowed, represented in number of isotopes
            int[] maxValues = MaximumFormula.GetIsotopes();

            // The current formula represented in isotopes
            int[] currentFormula = new int[maxValues.Length];

            // A list of all the isotopes masses
            double[] masses = new double[maxValues.Length];

            int length = maxValues.Length;

            for (int j = 0; j < length; j++)
            {
                if (minFormulaExists && j < minValues.Length)
                {
                    maxValues[j] -= minValues[j];
                }
                if (maxValues[j] == 0)
                {
                    continue;
                }
                masses[j] = PeriodicTable.GetIsotope(j).AtomicMass;
            }
            masses[0] = PeriodicTable.GetIsotope(0).AtomicMass;

            GenerateFormulaHelper(correctedLowMass, correctedHighMass, masses, maxValues, length - 1, currentFormula, returnFormulas);

            if (minFormulaExists)
            {
                foreach (ChemicalFormula formula in returnFormulas)
                {
                    formula.Add(MinimumFormula);
                }
                if (minFormulaMass >= lowMass && minFormulaMass <= highMass)
                {
                    returnFormulas.Add(new ChemicalFormula(MinimumFormula));
                }
            }

            if (!sort)
            {
                return(returnFormulas);
            }
            double meanValue = (highMass + lowMass) / 2.0;

            return(returnFormulas.OrderBy(formula => Math.Abs(formula.MonoisotopicMass - meanValue)).Take(maxNumberOfResults));
        }