Exemplo n.º 1
0
        public override void TestAdd_IAtomContainer()
        {
            ICrystal crystal = (ICrystal)NewChemObject();

            IAtomContainer acetone = crystal.Builder.NewAtomContainer();
            IAtom          c1      = crystal.Builder.NewAtom("C");
            IAtom          c2      = crystal.Builder.NewAtom("C");
            IAtom          o       = crystal.Builder.NewAtom("O");
            IAtom          c3      = crystal.Builder.NewAtom("C");

            acetone.Atoms.Add(c1);
            acetone.Atoms.Add(c2);
            acetone.Atoms.Add(c3);
            acetone.Atoms.Add(o);
            IBond b1 = crystal.Builder.NewBond(c1, c2, BondOrder.Single);
            IBond b2 = crystal.Builder.NewBond(c1, o, BondOrder.Double);
            IBond b3 = crystal.Builder.NewBond(c1, c3, BondOrder.Single);

            acetone.Bonds.Add(b1);
            acetone.Bonds.Add(b2);
            acetone.Bonds.Add(b3);

            crystal.Add(acetone);
            Assert.AreEqual(4, crystal.Atoms.Count);
            Assert.AreEqual(3, crystal.Bonds.Count);
        }
Exemplo n.º 2
0
        public virtual void TestStateChanged_EventPropagation_Crystal()
        {
            ChemObjectListenerImpl listener = new ChemObjectListenerImpl();
            IChemModel chemObject = (IChemModel)NewChemObject();
            chemObject.Listeners.Add(listener);

            ICrystal crystal = chemObject.Builder.NewCrystal();
            chemObject.Crystal = crystal;
            Assert.IsTrue(listener.Changed);
            // reset the listener
            listener.Reset();
            Assert.IsFalse(listener.Changed);
            // changing the set should trigger a change event in the IChemModel
            crystal.Add(chemObject.Builder.NewAtomContainer());
            Assert.IsTrue(listener.Changed);
        }
Exemplo n.º 3
0
        public virtual void TestStateChanged_ButNotAfterRemoval_Crystal()
        {
            ChemObjectListenerImpl listener = new ChemObjectListenerImpl();
            IChemModel chemObject = (IChemModel)NewChemObject();
            chemObject.Listeners.Add(listener);

            ICrystal crystal = chemObject.Builder.NewCrystal();
            chemObject.Crystal = crystal;
            Assert.IsTrue(listener.Changed);
            // remove the set from the IChemModel
            chemObject.Crystal = null;
            // reset the listener
            listener.Reset();
            Assert.IsFalse(listener.Changed);
            // changing the set must *not* trigger a change event in the IChemModel
            crystal.Add(chemObject.Builder.NewAtomContainer());
            Assert.IsFalse(listener.Changed);
        }
Exemplo n.º 4
0
        /// <summary>
        ///  Private method that actually parses the input to read a ChemFile
        ///  object.
        ///
        ///  Each PMP frame is stored as a Crystal in a ChemModel. The PMP
        ///  file is stored as a ChemSequence of ChemModels.
        /// </summary>
        /// <returns>A ChemFile containing the data parsed from input.</returns>
        private IChemFile ReadChemFile(IChemFile chemFile)
        {
            IChemSequence chemSequence = chemFile.Builder.NewChemSequence();
            IChemModel    chemModel    = chemFile.Builder.NewChemModel();
            ICrystal      crystal      = chemFile.Builder.NewCrystal();

            try
            {
                string line = ReadLine();
                while (line != null)
                {
                    if (line.StartsWith("%%Header Start", StringComparison.Ordinal))
                    {
                        // parse Header section
                        while (line != null && !(line.StartsWith("%%Header End", StringComparison.Ordinal)))
                        {
                            if (line.StartsWith("%%Version Number", StringComparison.Ordinal))
                            {
                                string version = ReadLine().Trim();
                                if (!string.Equals(version, "3.00", StringComparison.Ordinal))
                                {
                                    Trace.TraceError("The PMPReader only supports PMP files with version 3.00");
                                    return(null);
                                }
                            }
                            line = ReadLine();
                        }
                    }
                    else if (line.StartsWith("%%Model Start", StringComparison.Ordinal))
                    {
                        // parse Model section
                        modelStructure = chemFile.Builder.NewAtomContainer();
                        while (line != null && !(line.StartsWith("%%Model End", StringComparison.Ordinal)))
                        {
                            var objHeaderMatcher = objHeader.Match(line);
                            if (objHeaderMatcher.Success)
                            {
                                string obj = objHeaderMatcher.Groups[2].Value;
                                ConstructObject(chemFile.Builder, obj);
                                int id = int.Parse(objHeaderMatcher.Groups[1].Value, NumberFormatInfo.InvariantInfo);
                                // Debug.WriteLine(object + " id: " + id);
                                line = ReadLine();
                                while (line != null && !(string.Equals(line.Trim(), ")", StringComparison.Ordinal)))
                                {
                                    // parse object command (or new object header)
                                    var objCommandMatcher = objCommand.Match(line);
                                    objHeaderMatcher = objHeader.Match(line);
                                    if (objHeaderMatcher.Success)
                                    {
                                        // ok, forget about nesting and hope for the best
                                        obj = objHeaderMatcher.Groups[2].Value;
                                        id  = int.Parse(objHeaderMatcher.Groups[1].Value, NumberFormatInfo.InvariantInfo);
                                        ConstructObject(chemFile.Builder, obj);
                                    }
                                    else if (objCommandMatcher.Success)
                                    {
                                        string format  = objCommandMatcher.Groups[1].Value;
                                        string command = objCommandMatcher.Groups[2].Value;
                                        string field   = objCommandMatcher.Groups[3].Value;

                                        ProcessModelCommand(obj, command, format, field);
                                    }
                                    else
                                    {
                                        Trace.TraceWarning("Skipping line: " + line);
                                    }
                                    line = ReadLine();
                                }
                                if (chemObject is IAtom)
                                {
                                    atomids[id] = modelStructure.Atoms.Count;
                                    atomZOrders[int.Parse(chemObject.GetProperty <string>(PMP_ZORDER), NumberFormatInfo.InvariantInfo)] = id;
                                    atomGivenIds[int.Parse(chemObject.GetProperty <string>(PMP_ID), NumberFormatInfo.InvariantInfo)]    = id;
                                    modelStructure.Atoms.Add((IAtom)chemObject);
                                }
                                else if (chemObject is IBond)
                                {
                                    // ignored: bonds may be defined before their
                                    // atoms so their handling is deferred until the
                                    // end of the model
                                }
                                else
                                {
                                    Trace.TraceError("chemObject is not initialized or of bad class type");
                                }
                            }
                            line = ReadLine();
                        }
                        if (line.StartsWith("%%Model End", StringComparison.Ordinal))
                        {
                            // during the Model Start, all bonds are cached as PMP files might
                            // define bonds *before* the involved atoms :(
                            // the next lines dump the cache into the atom container

                            int bondsFound = bondids.Count;
                            Debug.WriteLine($"Found #bonds: {bondsFound}");
                            Debug.WriteLine($"#atom ones: {bondAtomOnes.Count}");
                            Debug.WriteLine($"#atom twos: {bondAtomTwos.Count}");
                            Debug.WriteLine($"#orders: {bondOrders.Count}");
                            foreach (var index in bondids.Keys)
                            {
                                if (!bondOrders.TryGetValue(index, out double order))
                                {
                                    order = 1;
                                }
                                Debug.WriteLine($"index: {index}");
                                Debug.WriteLine($"ones: {bondAtomOnes[index]}");
                                IAtom atom1 = modelStructure.Atoms[atomids[bondAtomOnes[index]]];
                                IAtom atom2 = modelStructure.Atoms[atomids[bondAtomTwos[index]]];
                                IBond bond  = modelStructure.Builder.NewBond(atom1, atom2);
                                if (order == 1.0)
                                {
                                    bond.Order = BondOrder.Single;
                                }
                                else if (order == 2.0)
                                {
                                    bond.Order = BondOrder.Double;
                                }
                                else if (order == 3.0)
                                {
                                    bond.Order = BondOrder.Triple;
                                }
                                else if (order == 4.0)
                                {
                                    bond.Order = BondOrder.Quadruple;
                                }
                                modelStructure.Bonds.Add(bond);
                            }
                        }
                    }
                    else if (line.StartsWith("%%Traj Start", StringComparison.Ordinal))
                    {
                        chemSequence = chemFile.Builder.NewChemSequence();
                        double energyFragment = 0.0;
                        double energyTotal    = 0.0;
                        int    Z = 1;
                        while (line != null && !(line.StartsWith("%%Traj End", StringComparison.Ordinal)))
                        {
                            if (line.StartsWith("%%Start Frame", StringComparison.Ordinal))
                            {
                                chemModel = chemFile.Builder.NewChemModel();
                                crystal   = chemFile.Builder.NewCrystal();
                                while (line != null && !(line.StartsWith("%%End Frame", StringComparison.Ordinal)))
                                {
                                    // process frame data
                                    if (line.StartsWith("%%Atom Coords", StringComparison.Ordinal))
                                    {
                                        // calculate Z: as it is not explicitely given, try to derive it from the
                                        // energy per fragment and the total energy
                                        if (energyFragment != 0.0 && energyTotal != 0.0)
                                        {
                                            Z = (int)Math.Round(energyTotal / energyFragment);
                                            Debug.WriteLine($"Z derived from energies: {Z}");
                                        }
                                        // add atomC as atoms to crystal
                                        int expatoms = modelStructure.Atoms.Count;
                                        for (int molCount = 1; molCount <= Z; molCount++)
                                        {
                                            IAtomContainer clone = modelStructure.Builder.NewAtomContainer();
                                            for (int i = 0; i < expatoms; i++)
                                            {
                                                line = ReadLine();
                                                IAtom a  = clone.Builder.NewAtom();
                                                var   st = Strings.Tokenize(line, ' ');
                                                a.Point3D        = new Vector3(double.Parse(st[0], NumberFormatInfo.InvariantInfo), double.Parse(st[1], NumberFormatInfo.InvariantInfo), double.Parse(st[2], NumberFormatInfo.InvariantInfo));
                                                a.CovalentRadius = 0.6;
                                                IAtom modelAtom = modelStructure.Atoms[atomids[atomGivenIds[i + 1]]];
                                                a.Symbol = modelAtom.Symbol;
                                                clone.Atoms.Add(a);
                                            }
                                            rebonder.Rebond(clone);
                                            crystal.Add(clone);
                                        }
                                    }
                                    else if (line.StartsWith("%%E/Frag", StringComparison.Ordinal))
                                    {
                                        line           = ReadLine().Trim();
                                        energyFragment = double.Parse(line, NumberFormatInfo.InvariantInfo);
                                    }
                                    else if (line.StartsWith("%%Tot E", StringComparison.Ordinal))
                                    {
                                        line        = ReadLine().Trim();
                                        energyTotal = double.Parse(line, NumberFormatInfo.InvariantInfo);
                                    }
                                    else if (line.StartsWith("%%Lat Vects", StringComparison.Ordinal))
                                    {
                                        line = ReadLine();
                                        IList <string> st;
                                        st        = Strings.Tokenize(line, ' ');
                                        crystal.A = new Vector3(double.Parse(st[0], NumberFormatInfo.InvariantInfo), double.Parse(st[1], NumberFormatInfo.InvariantInfo), double.Parse(st[2], NumberFormatInfo.InvariantInfo));
                                        line      = ReadLine();
                                        st        = Strings.Tokenize(line, ' ');
                                        crystal.B = new Vector3(double.Parse(st[0], NumberFormatInfo.InvariantInfo), double.Parse(st[1], NumberFormatInfo.InvariantInfo), double.Parse(st[2], NumberFormatInfo.InvariantInfo));
                                        line      = ReadLine();
                                        st        = Strings.Tokenize(line, ' ');
                                        crystal.C = new Vector3(double.Parse(st[0], NumberFormatInfo.InvariantInfo), double.Parse(st[1], NumberFormatInfo.InvariantInfo), double.Parse(st[2], NumberFormatInfo.InvariantInfo));
                                    }
                                    else if (line.StartsWith("%%Space Group", StringComparison.Ordinal))
                                    {
                                        line = ReadLine().Trim();

                                        // standardize space group name. See Crystal.SetSpaceGroup()
                                        if (string.Equals("P 21 21 21 (1)", line, StringComparison.Ordinal))
                                        {
                                            crystal.SpaceGroup = "P 2_1 2_1 2_1";
                                        }
                                        else
                                        {
                                            crystal.SpaceGroup = "P1";
                                        }
                                    }
                                    else
                                    {
                                    }
                                    line = ReadLine();
                                }
                                chemModel.Crystal = crystal;
                                chemSequence.Add(chemModel);
                            }
                            line = ReadLine();
                        }
                        chemFile.Add(chemSequence);
                    }
                    else
                    {
                        // disregard line
                    }
                    // read next line
                    line = ReadLine();
                }
            }
            catch (IOException e)
            {
                Trace.TraceError($"An IOException happened: {e.Message}");
                Debug.WriteLine(e);
                chemFile = null;
            }
            catch (CDKException e)
            {
                Trace.TraceError($"An CDKException happened: {e.Message}");
                Debug.WriteLine(e);
                chemFile = null;
            }

            return(chemFile);
        }