Exemple #1
0
        private IChemFile ReadChemFile(IChemFile file)
        {
            IChemSequence seq     = file.Builder.NewChemSequence();
            IChemModel    model   = file.Builder.NewChemModel();
            ICrystal      crystal = null;

            int     lineNumber = 0;
            Vector3 a, b, c;

            try
            {
                string line = input.ReadLine();
                while (line != null)
                {
                    Debug.WriteLine($"{lineNumber++}: {line}");
                    if (line.StartsWith("frame:", StringComparison.Ordinal))
                    {
                        Debug.WriteLine("found new frame");
                        model   = file.Builder.NewChemModel();
                        crystal = file.Builder.NewCrystal();

                        // assume the file format is correct

                        Debug.WriteLine("reading spacegroup");
                        line = input.ReadLine();
                        Debug.WriteLine($"{lineNumber++}: {line}");
                        crystal.SpaceGroup = line;

                        Debug.WriteLine("reading unit cell axes");
                        Vector3 axis = new Vector3();
                        Debug.WriteLine("parsing A: ");
                        line = input.ReadLine();
                        Debug.WriteLine($"{lineNumber++}: {line}");
                        axis.X = FortranFormat.Atof(line);
                        line   = input.ReadLine();
                        Debug.WriteLine($"{lineNumber++}: {line}");
                        axis.Y = FortranFormat.Atof(line);
                        line   = input.ReadLine();
                        Debug.WriteLine($"{lineNumber++}: {line}");
                        axis.Z    = FortranFormat.Atof(line);
                        crystal.A = axis;
                        axis      = new Vector3();
                        Debug.WriteLine("parsing B: ");
                        line = input.ReadLine();
                        Debug.WriteLine($"{lineNumber++}: {line}");
                        axis.X = FortranFormat.Atof(line);
                        line   = input.ReadLine();
                        Debug.WriteLine($"{lineNumber++}: {line}");
                        axis.Y = FortranFormat.Atof(line);
                        line   = input.ReadLine();
                        Debug.WriteLine($"{lineNumber++}: {line}");
                        axis.Z    = FortranFormat.Atof(line);
                        crystal.B = axis;
                        axis      = new Vector3();
                        Debug.WriteLine("parsing C: ");
                        line = input.ReadLine();
                        Debug.WriteLine($"{lineNumber++}: {line}");
                        axis.X = FortranFormat.Atof(line);
                        line   = input.ReadLine();
                        Debug.WriteLine($"{lineNumber++}: {line}");
                        axis.Y = FortranFormat.Atof(line);
                        line   = input.ReadLine();
                        Debug.WriteLine($"{lineNumber++}: {line}");
                        axis.Z    = FortranFormat.Atof(line);
                        crystal.C = axis;
                        Debug.WriteLine($"Crystal: {crystal}");
                        a = crystal.A;
                        b = crystal.B;
                        c = crystal.C;

                        Debug.WriteLine("Reading number of atoms");
                        line = input.ReadLine();
                        Debug.WriteLine($"{lineNumber++}: {line}");
                        int atomsToRead = int.Parse(line, NumberFormatInfo.InvariantInfo);

                        Debug.WriteLine("Reading no molecules in assym unit cell");
                        line = input.ReadLine();
                        Debug.WriteLine($"{lineNumber++}: {line}");
                        int Z = int.Parse(line, NumberFormatInfo.InvariantInfo);
                        crystal.Z = Z;

                        string  symbol;
                        double  charge;
                        Vector3 cart;
                        for (int i = 1; i <= atomsToRead; i++)
                        {
                            cart = new Vector3();
                            line = input.ReadLine();
                            Debug.WriteLine($"{lineNumber++}: {line}");
                            symbol = line.Substring(0, line.IndexOf(':'));
                            charge = double.Parse(line.Substring(line.IndexOf(':') + 1), NumberFormatInfo.InvariantInfo);
                            line   = input.ReadLine();
                            Debug.WriteLine($"{lineNumber++}: {line}");
                            cart.X = double.Parse(line, NumberFormatInfo.InvariantInfo); // x
                            line   = input.ReadLine();
                            Debug.WriteLine($"{lineNumber++}: {line}");
                            cart.Y = double.Parse(line, NumberFormatInfo.InvariantInfo); // y
                            line   = input.ReadLine();
                            Debug.WriteLine($"{lineNumber++}: {line}");
                            cart.Z = double.Parse(line, NumberFormatInfo.InvariantInfo); // z
                            IAtom atom = file.Builder.NewAtom(symbol);
                            atom.Charge = charge;
                            // convert Cartesian coords to fractional
                            Vector3 frac = CrystalGeometryTools.CartesianToFractional(a, b, c, cart);
                            atom.FractionalPoint3D = frac;
                            crystal.Atoms.Add(atom);
                            Debug.WriteLine($"Added atom: {atom}");
                        }

                        model.Crystal = crystal;
                        seq.Add(model);
                    }
                    else
                    {
                        Debug.WriteLine("Format seems broken. Skipping these lines:");
                        while (line != null && !line.StartsWith("frame:", StringComparison.Ordinal))
                        {
                            line = input.ReadLine();
                            Debug.WriteLine($"{lineNumber++}: {line}");
                        }
                        Debug.WriteLine("Ok, resynched: found new frame");
                    }
                }
                file.Add(seq);
            }
            catch (Exception exception)
            {
                if (!(exception is IOException || exception is ArgumentException))
                {
                    throw;
                }
                string message = "Error while parsing CrystClust file: " + exception.Message;
                Trace.TraceError(message);
                Debug.WriteLine(exception);
                throw new CDKException(message, exception);
            }
            return(file);
        }
Exemple #2
0
        private string ProcessAtomLoopBlock(string firstLine)
        {
            int    atomLabel              = -1; // -1 means not found in this block
            int    atomSymbol             = -1;
            int    atomFractX             = -1;
            int    atomFractY             = -1;
            int    atomFractZ             = -1;
            int    atomRealX              = -1;
            int    atomRealY              = -1;
            int    atomRealZ              = -1;
            string line                   = firstLine.Trim();
            int    headerCount            = 0;
            bool   hasParsableInformation = false;

            while (line != null && line[0] == '_')
            {
                headerCount++;
                if (line.Equals("_atom_site_label", StringComparison.Ordinal) || line.Equals("_atom_site_label_atom_id", StringComparison.Ordinal))
                {
                    atomLabel = headerCount;
                    hasParsableInformation = true;
                    Trace.TraceInformation($"label found in col: {atomLabel}");
                }
                else if (line.StartsWith("_atom_site_fract_x", StringComparison.Ordinal))
                {
                    atomFractX             = headerCount;
                    hasParsableInformation = true;
                    Trace.TraceInformation("frac x found in col: " + atomFractX);
                }
                else if (line.StartsWith("_atom_site_fract_y", StringComparison.Ordinal))
                {
                    atomFractY             = headerCount;
                    hasParsableInformation = true;
                    Trace.TraceInformation("frac y found in col: " + atomFractY);
                }
                else if (line.StartsWith("_atom_site_fract_z", StringComparison.Ordinal))
                {
                    atomFractZ             = headerCount;
                    hasParsableInformation = true;
                    Trace.TraceInformation("frac z found in col: " + atomFractZ);
                }
                else if (string.Equals(line, "_atom_site.Cartn_x", StringComparison.Ordinal))
                {
                    atomRealX = headerCount;
                    hasParsableInformation = true;
                    Trace.TraceInformation("cart x found in col: " + atomRealX);
                }
                else if (string.Equals(line, "_atom_site.Cartn_y", StringComparison.Ordinal))
                {
                    atomRealY = headerCount;
                    hasParsableInformation = true;
                    Trace.TraceInformation("cart y found in col: " + atomRealY);
                }
                else if (string.Equals(line, "_atom_site.Cartn_z", StringComparison.Ordinal))
                {
                    atomRealZ = headerCount;
                    hasParsableInformation = true;
                    Trace.TraceInformation("cart z found in col: " + atomRealZ);
                }
                else if (string.Equals(line, "_atom_site.type_symbol", StringComparison.Ordinal))
                {
                    atomSymbol             = headerCount;
                    hasParsableInformation = true;
                    Trace.TraceInformation("type_symbol found in col: " + atomSymbol);
                }
                else
                {
                    Trace.TraceWarning("Ignoring atom loop block field: " + line);
                }
                line = input.ReadLine().Trim();
            }
            if (!hasParsableInformation)
            {
                Trace.TraceInformation("No parsable info found");
                return(SkipLoopBody(line));
            }
            else
            {
                // now that headers are parsed, read the data
                while (line != null && line.Length > 0 &&
                       line[0] != '#' &&
                       line[0] != '_' &&
                       !line.StartsWith("loop_", StringComparison.Ordinal) &&
                       !line.StartsWith("data_", StringComparison.Ordinal))
                {
                    Debug.WriteLine("new row");
                    var tokenizer = Strings.Tokenize(line);
                    if (tokenizer.Count < headerCount)
                    {
                        Trace.TraceWarning("Column count mismatch; assuming continued on next line");
                        Debug.WriteLine($"Found #expected, #found:{headerCount}, {tokenizer.Count}");
                        tokenizer = Strings.Tokenize(line + input.ReadLine());
                    }
                    int colIndex = 0;
                    // process one row
                    IAtom   atom          = crystal.Builder.NewAtom("C");
                    Vector3 frac          = new Vector3();
                    Vector3 real          = new Vector3();
                    bool    hasFractional = false;
                    bool    hasCartesian  = false;
                    foreach (var field in tokenizer)
                    {
                        colIndex++;
                        Debug.WriteLine("Parsing col,token: " + colIndex + "=" + field);
                        if (colIndex == atomLabel)
                        {
                            if (atomSymbol == -1)
                            {
                                // no atom symbol found, use label
                                string element = ExtractFirstLetters(field);
                                atom.Symbol = element;
                            }
                            atom.Id = field;
                        }
                        else if (colIndex == atomFractX)
                        {
                            hasFractional = true;
                            frac.X        = ParseIntoDouble(field);
                        }
                        else if (colIndex == atomFractY)
                        {
                            hasFractional = true;
                            frac.Y        = ParseIntoDouble(field);
                        }
                        else if (colIndex == atomFractZ)
                        {
                            hasFractional = true;
                            frac.Z        = ParseIntoDouble(field);
                        }
                        else if (colIndex == atomSymbol)
                        {
                            atom.Symbol = field;
                        }
                        else if (colIndex == atomRealX)
                        {
                            hasCartesian = true;
                            Debug.WriteLine("Adding x3: " + ParseIntoDouble(field));
                            real.X = ParseIntoDouble(field);
                        }
                        else if (colIndex == atomRealY)
                        {
                            hasCartesian = true;
                            Debug.WriteLine("Adding y3: " + ParseIntoDouble(field));
                            real.Y = ParseIntoDouble(field);
                        }
                        else if (colIndex == atomRealZ)
                        {
                            hasCartesian = true;
                            Debug.WriteLine("Adding x3: " + ParseIntoDouble(field));
                            real.Z = ParseIntoDouble(field);
                        }
                    }
                    if (hasCartesian)
                    {
                        Vector3 a = crystal.A;
                        Vector3 b = crystal.B;
                        Vector3 c = crystal.C;
                        frac = CrystalGeometryTools.CartesianToFractional(a, b, c, real);
                        atom.FractionalPoint3D = frac;
                    }
                    if (hasFractional)
                    {
                        atom.FractionalPoint3D = frac;
                    }
                    Debug.WriteLine($"Adding atom: {atom}");
                    crystal.Atoms.Add(atom);

                    // look up next row
                    line = input.ReadLine();
                    if (line != null)
                    {
                        line = line.Trim();
                    }
                }
            }
            return(line);
        }
Exemple #3
0
        // Private procedures

        private void WriteCrystal(ICrystal crystal)
        {
            var title = crystal.Title;

            if (title != null && title.Trim().Length > 0)
            {
                Writeln($"TITL {title.Trim()}");
            }
            else
            {
                Writeln("TITL Produced with CDK (http://cdk.sf.net/)");
            }
            Vector3 a       = crystal.A;
            Vector3 b       = crystal.B;
            Vector3 c       = crystal.C;
            double  alength = a.Length();
            double  blength = b.Length();
            double  clength = c.Length();
            double  alpha   = Vectors.RadianToDegree(Vectors.Angle(b, c));
            double  beta    = Vectors.RadianToDegree(Vectors.Angle(a, c));
            double  gamma   = Vectors.RadianToDegree(Vectors.Angle(a, b));

            Write("CELL " + 1.54184.ToString("F5", NumberFormatInfo.InvariantInfo) + "   ");
            Write(alength.ToString("F5", NumberFormatInfo.InvariantInfo) + "  ");
            Write(blength.ToString("F5", NumberFormatInfo.InvariantInfo) + "  ");
            Write(clength.ToString("F5", NumberFormatInfo.InvariantInfo) + "  ");
            Write(alpha.ToString("F4", NumberFormatInfo.InvariantInfo) + "  ");
            Write(beta.ToString("F4", NumberFormatInfo.InvariantInfo) + "  ");
            Write(gamma.ToString("F4", NumberFormatInfo.InvariantInfo) + "  ");
            Writeln("ZERR " + ((double)crystal.Z).ToString("F5", NumberFormatInfo.InvariantInfo)
                    + "    0.01000  0.01000   0.01000   0.0100   0.0100   0.0100");
            string spaceGroup = crystal.SpaceGroup;

            if (string.Equals("P1", spaceGroup, StringComparison.Ordinal))
            {
                Writeln("LATT  -1");
            }
            else if (string.Equals("P 2_1 2_1 2_1", spaceGroup, StringComparison.Ordinal))
            {
                Writeln("LATT  -1");
                Writeln("SYMM  1/2+X   , 1/2-Y   ,    -Z");
                Writeln("SYMM     -X   , 1/2+Y   , 1/2-Z");
                Writeln("SYMM  1/2-X   ,    -Y   , 1/2+Z");
            }
            string            elemNames  = "";
            string            elemCounts = "";
            IMolecularFormula formula    = MolecularFormulaManipulator.GetMolecularFormula(crystal);
            var asortedElements          = MolecularFormulaManipulator.Elements(formula).ToReadOnlyList();

            foreach (var element in asortedElements)
            {
                string symbol = element.Symbol;
                elemNames += symbol + "    ".Substring(symbol.Length);
                string countS = MolecularFormulaManipulator.GetElementCount(formula, element).ToString(NumberFormatInfo.InvariantInfo);
                elemCounts += countS + "    ".Substring(countS.Length);
            }
            Writeln("SFAC  " + elemNames);
            Writeln("UNIT  " + elemCounts);
            /* write atoms */
            for (int i = 0; i < crystal.Atoms.Count; i++)
            {
                IAtom   atom      = crystal.Atoms[i];
                Vector3 cartCoord = atom.Point3D.Value;
                Vector3 fracCoord = CrystalGeometryTools.CartesianToFractional(a, b, c, cartCoord);
                string  symbol    = atom.Symbol;
                string  output    = symbol + (i + 1);
                Write(output);
                for (int j = 1; j < 5 - output.Length; j++)
                {
                    Write(" ");
                }
                Write("     ");
                string elemID = null;
                for (int elemidx = 0; elemidx < asortedElements.Count; elemidx++)
                {
                    var elem = asortedElements[elemidx];
                    if (elem.Symbol.Equals(symbol, StringComparison.Ordinal))
                    {
                        elemID = (elemidx + 1).ToString(NumberFormatInfo.InvariantInfo);
                        break;
                    }
                }
                Write(elemID);
                Write("    ".Substring(elemID.Length));
                Write(fracCoord.X.ToString("F5", NumberFormatInfo.InvariantInfo) + "   ");
                Write(fracCoord.Y.ToString("F5", NumberFormatInfo.InvariantInfo) + "   ");
                Writeln(fracCoord.Y.ToString("F5", NumberFormatInfo.InvariantInfo) + "    11.00000    0.05000");
            }
            Writeln("END");
        }