예제 #1
0
파일: CMLFormula.cs 프로젝트: qize/NCDK
        /// <summary>
        /// checks that atomArray is in array format with unduplicated valid
        /// elements. must have elementType and count attributes of equal lengths.
        /// </summary>
        /// <param name="atomArray">to check (not modified)</param>
        /// <exception cref="ApplicationException">if invalid</exception>
        public static void CheckAtomArrayFormat(CMLAtomArray atomArray)
        {
            if (atomArray.HasElements)
            {
                throw new ApplicationException("No children allowed for formula/atomArray");
            }
            var elements = atomArray.ElementType;
            var counts   = atomArray.Count;

            if (elements == null || counts == null)
            {
                throw new ApplicationException("formula/atomArray must have elementType and count attributes");
            }
            if (elements.Count != counts.Count)
            {
                throw new ApplicationException("formula/atomArray must have equal length elementType and count values");
            }
            var elementSet = new HashSet <string>();

            for (int i = 0; i < elements.Count; i++)
            {
                if (elements[i] != null && !(elements[i].Equals("null", StringComparison.Ordinal)))
                {
                    if (elementSet.Contains(elements[i]))
                    {
                        throw new ApplicationException($"formula/atomArray@elementType has duplicate element: {elements[i]}");
                    }
                    elementSet.Add(elements[i]);
                    if (counts[i] <= 0 && !allowNegativeCounts)
                    {
                        throw new ApplicationException($"formula/atomArray@count has nonPositive value: {counts[i]}  {elements[i]}");
                    }
                }
            }
        }
예제 #2
0
파일: CMLFormula.cs 프로젝트: qize/NCDK
        /// <summary>
        /// Adds element and count to formula. If element is already known,
        /// increments the count.
        /// </summary>
        /// <param name="elementType">the element atomicSymbol</param>
        /// <param name="count">the element multiplier</param>
        public void Add(string elementType, double count)
        {
            CMLAtomArray atomArray = AtomArrayElements.FirstOrDefault();

            if (atomArray == null)
            {
                // if no atomArray , create from concise
                Normalize();
                // if still none, create new one with empty attributes
                if (atomArray == null)
                {
                    atomArray = new CMLAtomArray();
                    Add(atomArray);
                    atomArray.ElementType = Array.Empty <string>();
                    atomArray.Count       = Array.Empty <double>();
                }
            }
            var elements = GetElementTypes();

            if (elements == null)
            {
                elements = Array.Empty <string>();
            }
            var counts = GetCounts()?.ToArray();

            if (counts == null)
            {
                counts = Array.Empty <double>();
            }
            var  nelem = elements.Count;
            bool added = false;

            for (int i = 0; i < nelem; i++)
            {
                if (elements[i].Equals(elementType, StringComparison.Ordinal))
                {
                    counts[i] += count;
                    added      = true;
                    break;
                }
            }
            if (!added)
            {
                var newElem = elements.ToList();
                newElem.Add(elementType);
                var newCount = counts.ToList();
                newCount.Add(count);
                atomArray.ElementType = newElem;
                atomArray.Count       = newCount;
            }
            else
            {
                atomArray.ElementType = elements;
                atomArray.Count       = counts;
            }
            int    formalCharge = (this.Attribute(Attribute_formalCharge) == null) ? 0 : this.FormalCharge;
            string conciseS     = atomArray.GenerateConcise(formalCharge);

            SetAttributeValue(Attribute_concise, conciseS);
        }
예제 #3
0
파일: CMLFormula.cs 프로젝트: qize/NCDK
        CMLAtomArray CreateAndAddAtomArrayAndFormalChargeFromConcise(string concise)
        {
            var atomArray = new CMLAtomArray();

            if (concise != null)
            {
                var elements = new List <string>();
                var counts   = new List <double>();
                var tokens   = Regex.Split(concise, @"\s");
                var nelement = tokens.Length / 2;
                for (int i = 0; i < nelement; i++)
                {
                    var elem = tokens[2 * i];
                    var ce   = NCDK.ChemicalElement.OfSymbol(elem).AtomicNumber;
                    if (ce == AtomicNumbers.Unknown)
                    {
                        throw new ApplicationException($"Unknown chemical element: {elem}");
                    }
                    if (elements.Contains(elem))
                    {
                        throw new ApplicationException($"Duplicate element in concise: {elem}");
                    }
                    elements.Add(elem);
                    var countS = tokens[2 * i + 1];
                    try
                    {
                        counts.Add(double.Parse(countS, NumberFormatInfo.InvariantInfo));
                    }
                    catch (FormatException)
                    {
                        throw new ApplicationException($"Bad element count in concise: {countS}");
                    }
                }
                if (tokens.Length > nelement * 2)
                {
                    var chargeS = tokens[nelement * 2];
                    try
                    {
                        var formalCharge = int.Parse(chargeS, NumberFormatInfo.InvariantInfo);
                        FormalCharge = formalCharge;
                    }
                    catch (FormatException)
                    {
                        throw new ApplicationException($"Bad formal charge in concise: {chargeS}");
                    }
                }
                var countD = new double[nelement];
                for (int i = 0; i < nelement; i++)
                {
                    countD[i] = counts[i];
                }
                atomArray.ElementType = elements.ToArray();
                atomArray.Count       = countD;
            }
            Add(atomArray);
            return(atomArray);
        }
예제 #4
0
        public void Add(CMLAtom atom)
        {
            var aa = this.Element(XName_CML_atomArray);

            if (aa == null)
            {
                aa = new CMLAtomArray();
                this.Add(aa);
            }
            aa.Add(atom);
        }
예제 #5
0
파일: CMLFormula.cs 프로젝트: qize/NCDK
 // FIXME move to tools
 private string NormalizeConciseAndFormalCharge(string conciseS, int formalCharge)
 {
     if (conciseS != null)
     {
         CMLAtomArray atomArray = CreateAndAddAtomArrayAndFormalChargeFromConcise(conciseS);
         if (atomArray != null)
         {
             atomArray.Sort(SortType.CHFirst);
             conciseS = atomArray.GenerateConcise(formalCharge);
         }
     }
     return(conciseS);
 }
예제 #6
0
파일: CMLFormula.cs 프로젝트: qize/NCDK
        /// <summary>
        /// Count for corresponding element.
        /// No defaults.
        /// </summary>
        /// <returns>double[] array of element counts; or null for none.</returns>
        public IReadOnlyList <string> GetElementTypes()
        {
            CMLAtomArray atomArray = AtomArrayElements.FirstOrDefault();

            return(atomArray?.ElementType);
        }
예제 #7
0
파일: CMLFormula.cs 프로젝트: qize/NCDK
        /// <summary>
        /// Count for corresponding element.
        /// No defaults.
        /// </summary>
        /// <returns>double[] array of element counts; or null for none.</returns>
        public IReadOnlyList <double> GetCounts()
        {
            CMLAtomArray atomArray = AtomArrayElements.FirstOrDefault();

            return(atomArray?.Count);
        }
예제 #8
0
파일: CMLFormula.cs 프로젝트: qize/NCDK
        // element:   formula
        // element:   atomArray

        public void Normalize()
        {
            // create all possible renderings of formula
            // any or all may be present
            // concise
            var conciseAtt = this.Attribute(Attribute_concise);
            // formal charge
            int formalCharge = 0;

            if (this.Attribute(Attribute_formalCharge) != null)
            {
                formalCharge = int.Parse(this.Attribute(Attribute_formalCharge).Value, NumberFormatInfo.InvariantInfo);
            }
            string conciseS = conciseAtt?.Value;
            // convention
            string convention = this.Convention;
            // inline formula (might be SMILES)
            string inline = this.Inline;

            if (inline != null)
            {
                inline = inline.Trim();
            }

            // atomArray
            CMLAtomArray atomArray         = null;
            string       atomArray2Concise = null;
            var          atomArrays        = this.Elements(XName_CML_atomArray).Cast <CMLAtomArray>().ToReadOnlyList();

            if (atomArrays.Count > 1)
            {
                throw new ApplicationException($"Only one atomArray child allowed for formula; found: {atomArrays.Count}");
            }
            else if (atomArrays.Count == 1)
            {
                atomArray = atomArrays.First();
                atomArray.Sort(SortType.CHFirst);
                atomArray2Concise = atomArray.GenerateConcise(formalCharge);
            }

            // concise from inline
            if (inline != null)
            {
                if (SMILES.Equals(convention, StringComparison.Ordinal) ||
                    SMILES1.Equals(convention, StringComparison.Ordinal))
                {
                }
            }
            if (conciseS == null)
            {
                if (atomArray2Concise != null)
                {
                    conciseS = atomArray2Concise;
                }
            }
            if (conciseS != null)
            {
                conciseS = NormalizeConciseAndFormalCharge(conciseS, formalCharge);
            }
            // if no atomArray, create
            if (atomArray == null)
            {
                // causes problems with Jmol
            }
            else
            {
                CheckAtomArrayFormat(atomArray);
            }
            if (atomArray != null)
            {
                atomArray.Sort(SortType.CHFirst);
            }
            // check consistency
            if (atomArray2Concise != null &&
                !atomArray2Concise.Equals(conciseS, StringComparison.Ordinal))
            {
                throw new ApplicationException($"concise ({conciseS}) and atomArray ({atomArray2Concise}) differ");
            }
            if (conciseS != null)
            {
                // by this time we may have generated a non-zero formal charge, so normalize it into concise
                conciseS = NormalizeConciseAndFormalCharge(conciseS, this.FormalCharge);
                ForceConcise(conciseS);
            }
        }
예제 #9
0
        /// <summary>
        /// Customize Molecule.
        /// </summary>
        /// <param name="molecule"></param>
        /// <param name="nodeToAdd"></param>
        public void Customize(IAtomContainer molecule, object nodeToAdd)
        {
            if (!(nodeToAdd is CMLMolecule))
            {
                throw new CDKException("NodeToAdd must be of type nu.xom.Element!");
            }

            //The nodeToAdd
            CMLMolecule molToCustomize = (CMLMolecule)nodeToAdd;

            if ((molecule is MDMolecule))
            {
                MDMolecule mdmol = (MDMolecule)molecule;
                molToCustomize.Convention = "md:mdMolecule";
                molToCustomize.SetAttributeValue(XNamespace.Xmlns + "md", NS_MD.NamespaceName);

                //Residues
                if (mdmol.GetResidues().Count > 0)
                {
                    foreach (var residue in mdmol.GetResidues())
                    {
                        int number = residue.GetNumber();

                        CMLMolecule resMol = new CMLMolecule
                        {
                            DictRef = "md:residue",
                            Title   = residue.Name
                        };

                        //Append resNo
                        CMLScalar residueNumber = new CMLScalar(number);
                        residueNumber.SetAttributeValue(Attribute_dictRef, "md:resNumber");
                        resMol.Add(residueNumber);

                        // prefix for residue atom id
                        string rprefix = "r" + number;
                        //Append atoms
                        CMLAtomArray ar = new CMLAtomArray();
                        for (int i = 0; i < residue.Atoms.Count; i++)
                        {
                            CMLAtom cmlAtom = new CMLAtom
                            {
                                //                        Console.Out.WriteLine("atom ID: "+ residue.Atoms[i].Id);
                                //                        cmlAtom.AddAttribute(new Attribute("ref", residue.Atoms[i].Id));
                                // the next thing is better, but  exception
                                //
                                // setRef to keep consistent usage
                                // setId to satisfy Jumbo 54. need for all atoms to have id
                                Ref = residue.Atoms[i].Id,
                                Id  = rprefix + "_" + residue.Atoms[i].Id
                            };
                            ar.Add(cmlAtom);
                        }
                        resMol.Add(ar);

                        molToCustomize.Add(resMol);
                    }
                }

                //Chargegroups
                if (mdmol.GetChargeGroups().Count > 0)
                {
                    foreach (var chargeGroup in mdmol.GetChargeGroups())
                    {
                        int number = chargeGroup.GetNumber();

                        //FIXME: persist the ChargeGroup
                        CMLMolecule cgMol = new CMLMolecule
                        {
                            DictRef = "md:chargeGroup"
                        };
                        // etc: add name, refs to atoms etc

                        //Append chgrpNo
                        CMLScalar cgNo = new CMLScalar(number)
                        {
                            DictRef = "md:cgNumber"
                        };
                        cgMol.Add(cgNo);

                        // prefix for residue atom id
                        string cprefix = "cg" + number;

                        //Append atoms from chargeGroup as it is an AC
                        CMLAtomArray ar = new CMLAtomArray();
                        for (int i = 0; i < chargeGroup.Atoms.Count; i++)
                        {
                            CMLAtom cmlAtom = new CMLAtom
                            {
                                // setRef to keep consistent usage
                                // setId to satisfy Jumbo 5.4 need for all atoms to have id
                                Ref = chargeGroup.Atoms[i].Id,
                                Id  = cprefix + "_" + chargeGroup.Atoms[i].Id
                            };

                            //Append switching atom?
                            if (chargeGroup.Atoms[i].Equals(chargeGroup.GetSwitchingAtom()))
                            {
                                CMLScalar scalar = new CMLScalar
                                {
                                    DictRef = "md:switchingAtom"
                                };
                                cmlAtom.Add(scalar);
                            }
                            ar.Add(cmlAtom);
                        }
                        cgMol.Add(ar);

                        molToCustomize.Add(cgMol);
                    }
                }
            }
        }