Esempio n. 1
0
        private static Dictionary <Orbital, Vector3D> CalculateLonePairRepulsion(Graph <Atom, SimpleBond> graph,
                                                                                 IDictionary <uint, Vector3D> forceLookup)
        {
            var lonePairForceLookup = graph.Vertices
                                      .Select(v => (AtomWithOrbitals)v.Object)
                                      .SelectMany(atom => atom.LonePairs)
                                      .ToDictionary(o => o, o => new Vector3D(0, 0, 0));

            foreach (var vertex in graph.Vertices)
            {
                var adjacentVertices         = GraphAlgorithms.GetAdjacentVertices(graph, vertex).Cast <IVertex <Atom> >().ToList();
                var currentAtom              = (AtomWithOrbitals)vertex.Object;
                var filledOuterOrbitals      = currentAtom.OuterOrbitals.Where(o => o.IsFull).ToList();
                var orbitalNeighborVertexMap = MapBondOrbitalToNeighborVertex(
                    filledOuterOrbitals, currentAtom, adjacentVertices);
                for (var orbitalIdx1 = 0; orbitalIdx1 < filledOuterOrbitals.Count; orbitalIdx1++)
                {
                    var orbital1 = filledOuterOrbitals[orbitalIdx1];
                    for (var orbitalIdx2 = orbitalIdx1 + 1; orbitalIdx2 < filledOuterOrbitals.Count; orbitalIdx2++)
                    {
                        var orbital2       = filledOuterOrbitals[orbitalIdx2];
                        var repulsiveForce = CalculateRepulsiveForce(orbital1, orbital2);

                        var orbtial1Vector = currentAtom.Position
                                             .VectorTo(orbital1.MaximumElectronDensityPosition)
                                             .Normalize();
                        var orbital1ParallelForce  = repulsiveForce.ProjectOnto(orbtial1Vector);
                        var orbital1RepulsiveForce = (repulsiveForce - orbital1ParallelForce).ToVector3D();

                        var orbtial2Vector = currentAtom.Position
                                             .VectorTo(orbital2.MaximumElectronDensityPosition)
                                             .Normalize();
                        var orbital2ParallelForce  = repulsiveForce.ProjectOnto(orbtial2Vector);
                        var orbital2RepulsiveForce = (repulsiveForce - orbital2ParallelForce).ToVector3D();

                        if (orbital1.IsPartOfBond)
                        {
                            var neighborVertex = orbitalNeighborVertexMap[orbital1];
                            forceLookup[neighborVertex.Id] += orbital1RepulsiveForce;
                        }
                        else
                        {
                            lonePairForceLookup[orbital1] += orbital1RepulsiveForce;
                        }
                        if (orbital2.IsPartOfBond)
                        {
                            var neighborVertex = orbitalNeighborVertexMap[orbital2];
                            forceLookup[neighborVertex.Id] += -orbital2RepulsiveForce;
                        }
                        else
                        {
                            lonePairForceLookup[orbital2] += -orbital2RepulsiveForce;
                        }
                    }
                }
            }
            return(lonePairForceLookup);
        }
Esempio n. 2
0
        private static IEnumerable <IVertex <Atom> > PositionNeighborsAndLonePairs(Molecule molecule, IVertex <Atom> vertex)
        {
            var currentAtom = (AtomWithOrbitals)vertex.Object;

            var vertextEdges          = vertex.EdgeIds.Select(edgeId => molecule.MoleculeStructure.GetEdgeById(edgeId)).ToList();
            var adjacentVertices      = GraphAlgorithms.GetAdjacentVertices(molecule.MoleculeStructure, vertex).Cast <IVertex <Atom> >().ToList();
            var unpositionedNeighbors = adjacentVertices.Where(v => !v.Object.IsPositioned).ToList();

            var evenlyDistributedPoints = GetAtomSpherePoints(currentAtom, adjacentVertices);
            var evenlySpacePointsQueue  = new Queue <Point3D>(evenlyDistributedPoints);

            var neighborsReadyForPositioning = new List <IVertex <Atom> >();

            foreach (var neighbor in unpositionedNeighbors)
            {
                var atom = neighbor.Object;
                if (atom.IsPositioned)
                {
                    continue;
                }
                neighborsReadyForPositioning.Add(neighbor);
                if (atom.IsPositionFixed)
                {
                    atom.IsPositioned = true;
                    continue;
                }
                var connectingEdges  = vertextEdges.Where(edge => edge.HasVertex(neighbor.Id)).ToList();
                var bonds            = connectingEdges.Select(edge => (OrbitalBond)edge.Object);
                var bondLength       = bonds.Select(bond => bond.BondLength.Value).Average();
                var bondDirection    = evenlySpacePointsQueue.Dequeue().ToVector3D();
                var neighborPosition = currentAtom.Position + bondLength * bondDirection;
                atom.Position     = neighborPosition.To(SIPrefix.Pico, Unit.Meter);
                atom.IsPositioned = true;
            }

            var lonePairs = currentAtom.OuterOrbitals.Where(o => o.IsFull && !o.IsPartOfBond).ToList();

            foreach (var lonePair in lonePairs)
            {
                var lonePairDirection = evenlySpacePointsQueue.Dequeue().ToVector3D();

                var lonePairPosition = currentAtom.Position
                                       + currentAtom.Radius.Value * lonePairDirection;
                lonePair.MaximumElectronDensityPosition = lonePairPosition;
            }
            return(neighborsReadyForPositioning);
        }
Esempio n. 3
0
        private static void PositionSpecificNeighborAlongXAxis(Molecule molecule, IVertex <Atom> currentVertex, IVertex <Atom> neighborVertex)
        {
            var currentAtom  = currentVertex.Object;
            var neighborAtom = neighborVertex.Object;

            if (neighborAtom.IsPositioned)
            {
                return;
            }
            if (neighborAtom.IsPositionFixed)
            {
                neighborAtom.IsPositioned = true;
                return;
            }
            var adjacentVertices        = GraphAlgorithms.GetAdjacentVertices(molecule.MoleculeStructure, currentVertex).Cast <IVertex <Atom> >().ToList();
            var evenlyDistributedPoints = GetAtomSpherePoints((AtomWithOrbitals)currentAtom, adjacentVertices);
            var edgesToNeighbor         = currentVertex.EdgeIds
                                          .Select(edgeId => molecule.MoleculeStructure.GetEdgeById(edgeId))
                                          .Where(edge => edge.HasVertex(neighborVertex.Id))
                                          .ToList();

            if (!edgesToNeighbor.Any())
            {
                throw new ArgumentException("Vertex to be positioned is not a neighbor of the current vertex");
            }

            var bonds                  = edgesToNeighbor.Select(edge => (OrbitalBond)edge.Object);
            var bondLength             = bonds.Select(bond => bond.BondLength.Value).Average();
            var candidateAtomPositions = evenlyDistributedPoints
                                         .Select(bondDirection => currentAtom.Position + bondLength * bondDirection)
                                         .ToList();
            var     pointsFurtherAlongX = candidateAtomPositions.Where(p => p.X > currentAtom.Position.X).ToList();
            Point3D neighborPosition;

            if (pointsFurtherAlongX.Any())
            {
                neighborPosition = pointsFurtherAlongX
                                   .MinimumItem(p => p.DistanceToLine(new Point3D(0, 0, 0), new Point3D(1, 0, 0)));
            }
            else
            {
                neighborPosition = candidateAtomPositions
                                   .MinimumItem(p => p.DistanceToLine(new Point3D(0, 0, 0), new Point3D(1, 0, 0)));
            }
            neighborAtom.Position     = neighborPosition.To(SIPrefix.Pico, Unit.Meter);
            neighborAtom.IsPositioned = true;
        }
Esempio n. 4
0
        private static Graph <ApproximatedAminoAcid, OrbitalBond> ToGraph(ConvexHull <ApproximateAminoAcidVertex3D, DefaultConvexFace <ApproximateAminoAcidVertex3D> > convexHull)
        {
            var graph = new Graph <ApproximatedAminoAcid, OrbitalBond>();

            // Add vertices
            var convexHullToGraphVertexIdMap = new Dictionary <long, uint>();

            foreach (var hullVertex in convexHull.Points)
            {
                var graphVertex = new Vertex <ApproximatedAminoAcid>(graph.GetUnusedVertexId())
                {
                    Object = hullVertex.AminoAcid
                };
                graph.AddVertex(graphVertex);
                convexHullToGraphVertexIdMap.Add(hullVertex.Id, graphVertex.Id);
            }

            // Connect vertices
            foreach (var face in convexHull.Faces)
            {
                for (int v1Idx = 0; v1Idx < face.Vertices.Length - 1; v1Idx++)
                {
                    var vertex1        = face.Vertices[v1Idx];
                    var vertex1GraphId = convexHullToGraphVertexIdMap[vertex1.Id];
                    for (int v2Idx = v1Idx + 1; v2Idx < face.Vertices.Length; v2Idx++)
                    {
                        var vertex2          = face.Vertices[v2Idx];
                        var vertex2GraphId   = convexHullToGraphVertexIdMap[vertex2.Id];
                        var graphVertex1     = graph.GetVertexFromId(vertex1GraphId);
                        var adjacentVertices = GraphAlgorithms.GetAdjacentVertices(graph, graphVertex1);
                        if (!adjacentVertices.Select(v => v.Id).Contains(vertex2GraphId))
                        {
                            graph.AddEdge(new Edge <OrbitalBond>(graph.GetUnusedEdgeId(), vertex1GraphId, vertex2GraphId));
                        }
                    }
                }
            }
            return(graph);
        }
        public Dictionary <ApproximatedAminoAcid, ApproximateAminoAcidForces> Calculate(
            CompactnessMeasurerResult compactnessMeasurerResult)
        {
            // VALIDATED: Forces point in the right direction, chain is compacted.
            // If force is reversed, chain is stretched out to a line.

            var forceDictionary = new Dictionary <ApproximatedAminoAcid, ApproximateAminoAcidForces>();

            var convexHull = compactnessMeasurerResult.ConvexHull;

            foreach (var vertex in convexHull.Vertices)
            {
                var aminoAcid      = vertex.Object;
                var vertexPosition = aminoAcid.CarbonAlphaPosition;
                if (!forceDictionary.ContainsKey(aminoAcid))
                {
                    forceDictionary.Add(aminoAcid, new ApproximateAminoAcidForces());
                }

                var adjacentVertices = GraphAlgorithms.GetAdjacentVertices(convexHull, vertex).Cast <IVertex <ApproximatedAminoAcid> >();
                foreach (var adjacentVertex in adjacentVertices)
                {
                    var adjacentAminoAcid = adjacentVertex.Object;
                    var adjacentPosition  = adjacentAminoAcid.CarbonAlphaPosition;
                    var connectingVector  = vertexPosition.VectorTo(adjacentPosition);
                    var distance          = connectingVector.Magnitude();
                    var forceMagnitude    = ForceScaling * (1.0 + ForceDistanceScaling * distance.In(SIPrefix.Pico, Unit.Meter));
                    var forceDirection    = connectingVector.In(SIPrefix.Pico, Unit.Meter).Normalize().ToVector3D();
                    if (!forceDictionary.ContainsKey(adjacentAminoAcid))
                    {
                        forceDictionary.Add(adjacentAminoAcid, new ApproximateAminoAcidForces());
                    }
                    AddForce(forceDictionary[aminoAcid], forceDirection, forceMagnitude);
                    AddForce(forceDictionary[adjacentAminoAcid], -forceDirection, forceMagnitude);
                }
            }
            return(forceDictionary);
        }
Esempio n. 6
0
        public void RedistributeCharges(Molecule aminoAcid)
        {
            var newCharges = aminoAcid.MoleculeStructure.Vertices
                             .ToDictionary(vertex => vertex.Id, vertex => vertex.Object.EffectiveCharge);
            double chargeChange;

            do
            {
                var currentCharges = newCharges;
                var vertices       = aminoAcid.MoleculeStructure.Vertices;
                foreach (var vertex in vertices)
                {
                    var neighbors = GraphAlgorithms.GetAdjacentVertices(aminoAcid.MoleculeStructure, vertex)
                                    .Cast <IVertex <Atom> >()
                                    .Select(v => v.Object)
                                    .ToList();
                    var atoms = new[] { vertex.Object }.Concat(neighbors).ToList();
                    var chargeSum = atoms.Sum(x => x.EffectiveCharge.In(Unit.ElementaryCharge))
                                    - atoms.Count;
                    var electroNegativitySum = atoms.Sum(x => x.ElectroNegativity);
                    foreach (var atom in atoms)
                    {
                        atom.EffectiveCharge = (1 + chargeSum * (atom.ElectroNegativity / electroNegativitySum)).To(Unit.ElementaryCharge);
                    }
                }
                newCharges = aminoAcid.MoleculeStructure.Vertices
                             .ToDictionary(vertex => vertex.Id, vertex => vertex.Object.EffectiveCharge);
                chargeChange = aminoAcid.MoleculeStructure.Vertices
                               .Select(v => v.Id)
                               .Select(vId => (newCharges[vId] - currentCharges[vId]).Abs().In(Unit.ElementaryCharge))
                               .Max();

                //var effectiveCharges = aminoAcid.Atoms.OrderBy(atom => atom.EffectiveCharge)
                //    .Select(atom => new { Atom = atom, Charge = atom.EffectiveCharge.In(Unit.ElementaryCharge) })
                //    .ToList();
            } while (chargeChange > 0.01);
        }