Example #1
0
        /// <summary>
        /// Initialize the surface, generating the points on the accessible surface
        /// area of each atom as well as calculating the surface area of each atom.
        /// </summary>
        private void Init()
        {
            // invariants
            foreach (var atom in atoms)
            {
                if (atom.Point3D == null)
                {
                    throw new ArgumentException("One or more atoms had no 3D coordinate set");
                }
            }

            // get r_f and geometric center
            var    cp        = new Vector3(0, 0, 0);
            double maxRadius = 0;

            foreach (var atom in atoms)
            {
                var vdwr = PeriodicTable.GetVdwRadius(atom.Symbol).Value;
                if (vdwr + solventRadius > maxRadius)
                {
                    maxRadius = PeriodicTable.GetVdwRadius(atom.Symbol).Value + solventRadius;
                }

                cp.X = cp.X + atom.Point3D.Value.X;
                cp.Y = cp.Y + atom.Point3D.Value.Y;
                cp.Z = cp.Z + atom.Point3D.Value.Z;
            }
            cp.X = cp.X / atoms.Length;
            cp.Y = cp.Y / atoms.Length;
            cp.Z = cp.Z / atoms.Length;

            // do the tesselation
            var tess = new Tessellate("ico", tesslevel);

            tess.DoTessellate();
            Trace.TraceInformation($"Got tesselation, number of triangles = {tess.GetNumberOfTriangles()}");

            // get neighbor list
            var nbrlist = new NeighborList(atoms, maxRadius + solventRadius);

            Trace.TraceInformation("Got neighbor list");

            // loop over atoms and get surface points
            this.surfPoints = new List <Vector3> [atoms.Length];
            this.areas      = new double[atoms.Length];
            this.volumes    = new double[atoms.Length];

            for (int i = 0; i < atoms.Length; i++)
            {
                var pointDensity = tess.GetNumberOfTriangles() * 3;
                var points       = AtomicSurfacePoints(nbrlist, i, atoms[i], tess);
                TranslatePoints(i, points, pointDensity, atoms[i], cp);
            }
            Trace.TraceInformation("Obtained points, areas and volumes");
        }
Example #2
0
        private Vector3[][] AtomicSurfacePoints(NeighborList nbrlist, int currAtomIdx, IAtom atom, Tessellate tess)
        {
            var totalRadius      = PeriodicTable.GetVdwRadius(atom.Symbol).Value + solventRadius;
            var totalRadius2     = totalRadius * totalRadius;
            var twiceTotalRadius = 2 * totalRadius;

            var nlist = nbrlist.GetNeighbors(currAtomIdx);
            var data  = Arrays.CreateJagged <double>(nlist.Length, 4);

            for (int i = 0; i < nlist.Length; i++)
            {
                var x12 = atoms[nlist[i]].Point3D.Value.X - atom.Point3D.Value.X;
                var y12 = atoms[nlist[i]].Point3D.Value.Y - atom.Point3D.Value.Y;
                var z12 = atoms[nlist[i]].Point3D.Value.Z - atom.Point3D.Value.Z;

                var d2  = x12 * x12 + y12 * y12 + z12 * z12;
                var tmp = PeriodicTable.GetVdwRadius(atoms[nlist[i]].Symbol).Value + solventRadius;
                tmp = tmp * tmp;
                var thresh = (d2 + totalRadius2 - tmp) / twiceTotalRadius;

                data[i][0] = x12;
                data[i][1] = y12;
                data[i][2] = z12;
                data[i][3] = thresh;
            }

            var tessPoints = tess.GetTessAsPoint3ds();
            var points     = new List <Vector3[]>();

            foreach (var pt in tessPoints)
            {
                bool buried = false;
                foreach (var datum in data)
                {
                    if (datum[0] * pt.X + datum[1] * pt.Y + datum[2] * pt.Z > datum[3])
                    {
                        buried = true;
                        break;
                    }
                }
                if (!buried)
                {
                    var tmp = new Vector3[2];
                    tmp[0] = new Vector3(
                        totalRadius * pt.X + atom.Point3D.Value.X,
                        totalRadius * pt.Y + atom.Point3D.Value.Y,
                        totalRadius * pt.Z + atom.Point3D.Value.Z);
                    tmp[1] = pt;
                    points.Add(tmp);
                }
            }

            // the first column contains the transformed points
            // and the second column contains the points from the
            // original unit tesselation
            var ret = Arrays.CreateJagged <Vector3>(points.Count, 2);

            for (int i = 0; i < points.Count; i++)
            {
                var tmp = points[i];
                ret[i][0] = tmp[0];
                ret[i][1] = tmp[1];
            }
            return(ret);
        }