コード例 #1
0
        internal static ElementBase GetChemicalElement(XElement cmlElement, out string message)
        {
            message = "";
            XAttribute xa = cmlElement.Attribute(CMLConstants.AttributeElementType);

            if (xa != null)
            {
                string      symbol = xa.Value;
                ElementBase eb;
                AtomHelpers.TryParse(symbol, out eb);

                if (eb is Element element)
                {
                    return(element);
                }

                if (eb is FunctionalGroup functionalGroup)
                {
                    return(functionalGroup);
                }

                //if we got here then it went very wrong
                message = $"Unrecognised element '{symbol}' in {cmlElement}";
            }
            else
            {
                message = $"cml attribute 'elementType' missing from {cmlElement}";
            }

            return(null);
        }
コード例 #2
0
        internal static ElementBase GetElementOrFunctionalGroup(XElement cmlElement, out string message)
        {
            message = "";
            XAttribute xa = cmlElement.Attribute(CMLConstants.AttributeElementType);

            if (xa != null)
            {
                string      symbol = xa.Value;
                ElementBase eb;
                AtomHelpers.TryParse(symbol, out eb);

                if (eb is Element element)
                {
                    return(element);
                }

                if (eb is FunctionalGroup functionalGroup)
                {
                    // Fix Invalid data; Force internal FG to prime Element
                    if (functionalGroup.Internal)
                    {
                        AtomHelpers.TryParse(functionalGroup.Components[0].Component, out eb);
                        if (eb is Element chemicalElement)
                        {
                            return(chemicalElement);
                        }
                    }
                    return(functionalGroup);
                }

                //if we got here then it went very wrong
                message = $"Unrecognised element '{symbol}' in {cmlElement}";
            }
            else
            {
                message = $"cml attribute 'elementType' missing from {cmlElement}";
            }

            return(null);
        }
コード例 #3
0
        private void ReadAtoms(StreamReader reader, int atoms)
        {
            int idx = 0;

            while (!reader.EndOfStream && idx < atoms)
            {
                string line = SdFileConverter.GetNextLine(reader);
                if (!string.IsNullOrEmpty(line))
                {
                    // create atom
                    Atom thisAtom = new Atom();

                    double x = Double.Parse(GetSubString(line, 0, 9), CultureInfo.InvariantCulture);
                    double y = Double.Parse(GetSubString(line, 10, 9), CultureInfo.InvariantCulture);
                    double z = Double.Parse(GetSubString(line, 20, 9), CultureInfo.InvariantCulture);

                    // Inverting Y co-ordinate to make it the right way up.
                    thisAtom.Position = new Point(x, 0 - y);

                    // element type
                    string      elType = GetSubString(line, 31, 3);
                    ElementBase eb;
                    var         ok = AtomHelpers.TryParse(elType, out eb);
                    if (ok)
                    {
                        if (eb is Element element)
                        {
                            thisAtom.Element = element;
                        }

                        if (eb is FunctionalGroup functionalGroup)
                        {
                            thisAtom.Element = functionalGroup;

                            // Fix Invalid data; Force internal FG to prime Element
                            if (functionalGroup.Internal)
                            {
                                AtomHelpers.TryParse(functionalGroup.Components[0].Component, out eb);
                                if (eb is Element chemicalElement)
                                {
                                    thisAtom.Element = chemicalElement;
                                }
                            }
                        }
                    }
                    else
                    {
                        _molecule.Errors.Add($"{elType} at Line {SdFileConverter.LineNumber} is not a valid Element");
                        _molecule.Errors.Add($"{line}");
                    }

                    // isotope
                    int delta = ParseInteger(line, 34, 2);
                    if (delta != 0)
                    {
                        thisAtom.IsotopeNumber = delta;
                    }

                    // charge
                    int ch = ParseInteger(line, 36, 3);
                    thisAtom.FormalCharge   = FormalChargeFromMolfile(ch);
                    thisAtom.DoubletRadical = DoubletRadicalFromMolfile(ch);

                    // field 3 is atom parity (a *write-only* field, so not used)
                    // int parity = ParseInteger(line, 39, 3)

                    // field 4 hydrogen count
                    // int hCount = ParseInteger(line, 42, 3)

                    // field 5 stereoCareBox
                    // int field5 = ParseInteger(line, 45, 3)

                    // field 6 valency/oxidation state
                    // int oxState = ParseInteger(line, 48, 3)

                    // field 7 H0 designator
                    // int hZero = ParseInteger(line, 51, 3)

                    // atom-atom mapping
                    int atomMap = ParseInteger(line, 60, 3);
                    if (atomMap != 0)
                    {
                        // ToDo: What to do here ???
                    }

                    // inversion/retention flag
                    // int hZero = ParseInteger(line, 63, 3)

                    // exact change flag
                    // int hZero = ParseInteger(line, 66, 3)

                    idx++;

                    // Add atom to molecule
                    thisAtom.Id = $"a{idx}";
                    _molecule.AddAtom(thisAtom);
                    thisAtom.Parent = _molecule;
                    atomByNumber.Add(idx, thisAtom);
                }
            }
        }
コード例 #4
0
        private static void AddMolecule(dynamic data, Model newModel)
        {
            Dictionary <int, string> atoms = new Dictionary <int, string>();
            var         newMol             = new Molecule();
            ElementBase ce        = Globals.PeriodicTable.C;
            int         atomCount = 0;

            // GitHub: Issue #13 https://github.com/Chem4Word/Version3/issues/13
            if (data.a != null)
            {
                foreach (AtomJSON a in data.a)
                {
                    if (!string.IsNullOrEmpty(a.l))
                    {
                        ElementBase eb;
                        var         ok = AtomHelpers.TryParse(a.l, out eb);
                        if (ok)
                        {
                            if (eb is Element element)
                            {
                                ce = element;
                            }

                            if (eb is FunctionalGroup functionalGroup)
                            {
                                ce = functionalGroup;
                            }
                        }
                    }
                    else
                    {
                        ce = Globals.PeriodicTable.C;
                    }

                    Atom atom = new Atom()
                    {
                        Element  = ce,
                        Position = new Point(a.x, a.y)
                    };

                    if (a.c != null)
                    {
                        atom.FormalCharge = a.c.Value;
                    }

                    atoms.Add(atomCount++, atom.InternalId);
                    newMol.AddAtom(atom);
                    atom.Parent = newMol;
                }
            }

            if (data.b != null)
            {
                foreach (BondJSON b in data.b)
                {
                    string o;
                    if (b.o != null)
                    {
                        o = Globals.OrderValueToOrder(double.Parse(b.o.ToString()));
                    }
                    else
                    {
                        o = Globals.OrderSingle;
                    }

                    Globals.BondStereo s;
                    if (!string.IsNullOrEmpty(b.s))
                    {
                        if (o == Globals.OrderDouble)
                        {
                            if (b.s.Equals(Ambiguous))
                            {
                                s = Globals.BondStereo.Indeterminate;
                            }
                            else
                            {
                                s = Globals.BondStereo.None;
                            }
                        }
                        else
                        {
                            if (b.s.Equals(Recessed))
                            {
                                s = Globals.BondStereo.Hatch;
                            }
                            else if (b.s.Equals(Protruding))
                            {
                                s = Globals.BondStereo.Wedge;
                            }
                            else if (b.s.Equals(Ambiguous))
                            {
                                s = Globals.BondStereo.Indeterminate;
                            }
                            else
                            {
                                s = Globals.BondStereo.None;
                            }
                        }
                    }
                    else
                    {
                        s = Globals.BondStereo.None;
                    }

                    // Azure DevOps #715
                    if (b.b.HasValue && b.b.Value < atoms.Count && b.e.HasValue && b.e.Value < atoms.Count)
                    {
                        var  sa      = atoms[b.b.Value];
                        var  ea      = atoms[b.e.Value];
                        Bond newBond = new Bond()
                        {
                            StartAtomInternalId = sa,
                            EndAtomInternalId   = ea,
                            Stereo = s,
                            Order  = o
                        };
                        newMol.AddBond(newBond);
                        newBond.Parent = newMol;
                    }
                }
            }

            newModel.AddMolecule(newMol);
            newMol.Parent = newModel;
        }
コード例 #5
0
ファイル: FunctionalGroup.cs プロジェクト: rrsc/Version3-1
        /// <summary>
        /// Expand the Functional Group into a flattened list of terms
        /// </summary>
        /// <param name="reverse"></param>
        /// <param name="consolidate"></param>
        /// <returns></returns>
        public List <FunctionalGroupTerm> ExpandIntoTerms(bool reverse = false, bool consolidate = true)
        {
            List <FunctionalGroupTerm> result = new List <FunctionalGroupTerm>();

            if (ShowAsSymbol)
            {
                var term = new FunctionalGroupTerm
                {
                    IsAnchor = true
                };

                term.Parts = ExpandSymbol(Symbol);
                result.Add(term);
            }
            else
            {
                for (int i = 0; i < Components.Count; i++)
                {
                    var term = new FunctionalGroupTerm
                    {
                        IsAnchor = i == 0,
                        Parts    = ExpandGroupV2(Components[i])
                    };

                    result.Add(term);
                }
            }

            // Consolidate parts of each term
            if (consolidate)
            {
                foreach (var term in result)
                {
                    if (term.Parts.Count > 1)
                    {
                        var newParts = new List <FunctionalGroupPart>();

                        var newPart = term.Parts[0];
                        newParts.Add(newPart);

                        for (int i = 1; i < term.Parts.Count; i++)
                        {
                            if (term.Parts[i].Type == term.Parts[i - 1].Type)
                            {
                                newPart.Text += term.Parts[i].Text;
                            }
                            else
                            {
                                newPart = term.Parts[i];
                                newParts.Add(newPart);
                            }
                        }

                        term.Parts = newParts;
                    }
                }
            }

            if (Flippable && reverse)
            {
                result.Reverse();
            }

            return(result);

            // Local Functions

            // Ensure that Symbols such as "R{1}" and "{i}Pr" are expanded into parts
            List <FunctionalGroupPart> ExpandSymbol(string symbol)
            {
                List <FunctionalGroupPart> expanded = new List <FunctionalGroupPart>();

                if (symbol.Contains("{") || symbol.Contains("}"))
                {
                    var part = new FunctionalGroupPart();
                    foreach (char c in symbol)
                    {
                        switch (c)
                        {
                        case '{':
                            if (!string.IsNullOrEmpty(part.Text))
                            {
                                expanded.Add(part);
                            }

                            part = new FunctionalGroupPart
                            {
                                Type = FunctionalGroupPartType.Superscript
                            };
                            break;

                        case '}':
                            expanded.Add(part);
                            part = new FunctionalGroupPart();
                            break;

                        default:
                            part.Text += c;
                            break;
                        }
                    }

                    // Ensure that trailing characters are not lost
                    if (!string.IsNullOrEmpty(part.Text))
                    {
                        expanded.Add(part);
                    }
                }
                else
                {
                    expanded.Add(new FunctionalGroupPart
                    {
                        Text = symbol
                    });
                }

                return(expanded);
            }

            List <FunctionalGroupPart> ExpandGroupV2(Group componentGroup, bool flipped = false)
            {
                List <FunctionalGroupPart> expanded = new List <FunctionalGroupPart>();

                ElementBase elementBase;

                if (AtomHelpers.TryParse(componentGroup.Component, out elementBase))
                {
                    if (elementBase is Element element)
                    {
                        expanded.Add(new FunctionalGroupPart
                        {
                            Text = element.Symbol
                        });

                        if (componentGroup.Count != 1)
                        {
                            var part = new FunctionalGroupPart
                            {
                                Type = FunctionalGroupPartType.Subscript,
                                Text = $"{componentGroup.Count}"
                            };
                            expanded.Add(part);
                        }
                    }

                    if (elementBase is FunctionalGroup functionalGroup)
                    {
                        var part = new FunctionalGroupPart();

                        if (componentGroup.Count != 1)
                        {
                            part.Text += "(";
                            expanded.Add(part);
                            part = new FunctionalGroupPart();
                        }

                        if (functionalGroup.ShowAsSymbol)
                        {
                            if (!string.IsNullOrEmpty(part.Text))
                            {
                                expanded.Add(part);
                            }

                            expanded.AddRange(ExpandSymbol(functionalGroup.Symbol));
                            part = new FunctionalGroupPart();
                        }
                        else
                        {
                            if (functionalGroup.Flippable && flipped)
                            {
                                for (int ii = functionalGroup.Components.Count - 1; ii >= 0; ii--)
                                {
                                    expanded.AddRange(ExpandGroupV2(functionalGroup.Components[ii]));
                                }
                            }
                            else
                            {
                                foreach (var fgc in functionalGroup.Components)
                                {
                                    expanded.AddRange(ExpandGroupV2(fgc));
                                }
                            }
                        }

                        if (componentGroup.Count != 1)
                        {
                            part.Text += ")";
                            expanded.Add(part);

                            part = new FunctionalGroupPart
                            {
                                Type = FunctionalGroupPartType.Subscript,
                                Text = $"{componentGroup.Count}"
                            };
                            expanded.Add(part);

                            part = new FunctionalGroupPart();
                        }

                        // Ensure that trailing characters are not lost
                        if (!string.IsNullOrEmpty(part.Text))
                        {
                            expanded.Add(part);
                        }
                    }
                }

                return(expanded);
            }
        }