Represents a single isotope of a chemical element. Contains a unique number of protons and neutrons compared to every other isotope.
Пример #1
0
        /// <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);
        }
Пример #2
0
 /// <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]);
 }
Пример #3
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);
            }
        }
Пример #4
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);
     }
 }
Пример #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));
                }
            }
        }
Пример #6
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;
        }
Пример #7
0
        /// <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();
            }
        }
Пример #8
0
        /// <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);
        }
Пример #9
0
        /// <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);
 }
Пример #11
0
 public void RemoveConstraint(Isotope isotope)
 {
     MinimumFormula.Remove(isotope);
     MaximumFormula.Remove(isotope);
 }
Пример #12
0
        /// <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);
            }
        }
Пример #13
0
 /// <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 RemoveConstraint(Isotope isotope)
 {
     MinimumFormula.Remove(isotope);
     MaximumFormula.Remove(isotope);
 }
Пример #15
0
 public void AddConstraint(Isotope isotope, int min, int max)
 {
     MinimumFormula.Add(isotope, min);
     MaximumFormula.Add(isotope, max);
 }
Пример #16
0
 /// <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);
 }
Пример #17
0
 public void RemoveConstraint(Isotope isotope)
 {
     _minFormula.Remove(isotope);
     _maxFormula.Remove(isotope);
 }
Пример #18
0
 /// <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);
 }
Пример #19
0
 public void AddConstraint(Isotope isotope, int min, int max)
 {
     _minFormula.Add(isotope, min);
     _maxFormula.Add(isotope, max);
 }
Пример #20
0
        public int Count(string symbol, int atomicNumber)
        {
            Isotope isotope = PeriodicTable.GetElement(symbol)[atomicNumber];

            return(Count(isotope));
        }
Пример #21
0
 public void AddConstraint(Isotope isotope, Range<int> range)
 {
     AddConstraint(isotope, range.Minimum, range.Maximum);
 }
Пример #22
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));
        }
 public void AddConstraint(Isotope isotope, int min, int max)
 {
     MinimumFormula.Add(isotope, min);
     MaximumFormula.Add(isotope, max);
 }