public override object VisitChain([NotNull] smilesParser.ChainContext context)
 {
     foreach (IParseTree tree in context.children)
     {
         if (typeof(smilesParser.ChainContext).IsAssignableFrom(tree.GetType()))
         {
             VisitChain((smilesParser.ChainContext)tree);
         }
         else if (typeof(smilesParser.Branched_atomContext).IsAssignableFrom(tree.GetType()))
         {
             VisitBranched_atom((smilesParser.Branched_atomContext)tree);
         }
         else if (typeof(smilesParser.BondContext).IsAssignableFrom(tree.GetType()))
         {
             nextBond = (BondType)VisitBond((smilesParser.BondContext)tree);
         }
         else if (typeof(smilesParser.DotContext).IsAssignableFrom(tree.GetType()))
         {
             nextBond = (BondType)VisitDot((smilesParser.DotContext)tree);
         }
         else
         {
             nextBond = BondType.Any;
         }
     }
     return(null);
 }
Exemplo n.º 2
0
 public Bond(Node thisNode, Node thatNode, BondType t, Orientation o)
 {
     Node1       = thisNode;
     Node2       = thatNode;
     Type        = t;
     Orientation = o;
 }
Exemplo n.º 3
0
        public Bond AddBond(Atom atom, BondType type, BondStereo stereo, BondTopology topology, BondReactingCenterStatus rcStatus)
        {
            Bond b = new Bond(this, atom, type, BondStereo.NotStereoOrUseXYZ, BondTopology.Either, BondReactingCenterStatus.notACenter);

            this.BondedAtoms.Add(b);
            return(b);
        }
Exemplo n.º 4
0
        public void Align(uint[] instanceIds, ChainType chainType, Vex.Point target, List <Bond> addedBonds, List <Bond> previousBonds)
        {
            BondAttachment bt       = chainType.GetAttachment();
            BondType       bondType = chainType.IsAligned() ? BondType.Anchor : BondType.Spring;

            Bond b;
            Bond prev = null;

            for (int i = 0; i < instanceIds.Length - 1; i++)
            {
                uint id = instanceIds[i];

                if (chainType.IsDistributed())
                {
                    if (i > 0)
                    {
                        RemoveCollidingBond(id, bt, previousBonds, BondType.Anchor);
                    }
                    if (i < instanceIds.Length - 1)
                    {
                        BondAttachment btOpp = chainType.GetOppositeAttachment();
                        RemoveCollidingBond(id, btOpp, previousBonds, BondType.Anchor);
                    }
                }
                else
                {
                    RemoveCollidingBond(id, bt, previousBonds, BondType.Anchor);
                }

                b                = new Bond(id, bt, bondType);
                b.ChainType      = chainType;
                b.TargetLocation = target;
                AddBond(b);
                addedBonds.Add(b);

                b.Previous = prev;
                if (prev != null)
                {
                    prev.Next = b;
                }
                prev = b;
            }

            int  lastIndex = instanceIds.Length - 1;
            uint lastId    = instanceIds[lastIndex];

            RemoveCollidingBond(lastId, bt, previousBonds, BondType.Anchor);

            b                = new Bond(lastId, bt, bondType);
            b.ChainType      = chainType;
            b.TargetLocation = target;
            AddBond(b);
            addedBonds.Add(b);

            b.Previous = prev;
            prev.Next  = b;
        }
Exemplo n.º 5
0
            public BondLine(PointF p0, PointF p1, BondType bondType, BondAttachment attachment)
            {
                this.bondType   = bondType;
                this.attachment = attachment;
                this.p0         = p0;
                this.p1         = p1;

                offset = Point.Empty;
                GetOffset(p0, p1);
            }
 public Bond(Atom parent, Atom connectedAtom, BondType type, BondStereo stereo, BondTopology topology, BondReactingCenterStatus rcStatus)
 {
     ParentAtom     = parent;
     ConnectedAtom  = connectedAtom;
     BondType       = type;
     DrawType       = type;
     Stereo         = stereo;
     Topology       = topology;
     ReactingCenter = rcStatus;
     BondLength     = 0; // parent.CovalentRadius + connectedAtom.CovalentRadius;
 }
Exemplo n.º 7
0
        /// <summary>从本地加载氨基酸数据 </summary>
        public static async Task LoadDataAsync()
        {
            if (loaded)
            {
                throw new PolymerModelException("PolymerModel has been loaded");
            }
            string aminoacidData = await IOUtil.ReadInStreamingAssetsAsync(string.Empty, "Aminoacid.csv");

            AminoacidDt = CSVHelper.ReadCSVStr(aminoacidData);
            string connectionData = await IOUtil.ReadInStreamingAssetsAsync(string.Empty, "Connection.csv");

            ConnectionDt = CSVHelper.ReadCSVStr(connectionData);

            //将Connection数据表转化为字典,有助于后续的数据查找
            Dictionary <string, List <DataRow> > connectionDic = new Dictionary <string, List <DataRow> >();

            foreach (DataRow connectionDataRow in ConnectionDt.Rows)
            {
                string type = connectionDataRow["Type"].ToString();
                if (!connectionDic.ContainsKey(type))
                {
                    connectionDic.Add(type, new List <DataRow>());
                }
                connectionDic[type].Add(connectionDataRow);
            }

            //遍历氨基酸数据表 + connectionDic 一起构建氨基酸数据结构
            foreach (DataRow aminoacidDataRow in AminoacidDt.Rows)
            {
                string        type          = aminoacidDataRow["Type"].ToString();
                AminoacidType aminoacidType = (AminoacidType)Enum.Parse(typeof(AminoacidType), type);
                string        chinese       = aminoacidDataRow["Chinese"].ToString();
                bool          isStandard    = aminoacidDataRow["IsStandard"].ToString() == "1";
                string[]      atomNames     = aminoacidDataRow["Atoms"].ToString().Trim('[', ']').Split(' ');
                Dictionary <KeyValuePair <string, string>, BondType> connection = new Dictionary <KeyValuePair <string, string>, BondType>();
                if (connectionDic.ContainsKey(type))
                {
                    //若该残基包含键
                    foreach (DataRow connectionDataRow in connectionDic[type])
                    {
                        string   firstAtom  = connectionDataRow["First"].ToString();
                        string   secondAtom = connectionDataRow["Second"].ToString();
                        BondType bondType   = (BondType)Enum.Parse(typeof(BondType), connectionDataRow["BondType"].ToString());
                        connection.Add(new KeyValuePair <string, string>(firstAtom, secondAtom), bondType);
                    }
                }
                Aminoacid aminoacid = new Aminoacid(aminoacidType, chinese, isStandard, atomNames, connection);
                Aminoacid.Aminoacids.Add(aminoacid.Type, aminoacid);
            }
            loaded = true;
        }
Exemplo n.º 8
0
 public Bond(float x1 = 0, float y1 = 0, float x2 = 0, float y2 = 0, float thickness = 1.5f, SKColor?colour = null, BondType typeOfBond = BondType.Single, BondStyle subtype = BondStyle.Plain, int anchorID1 = -1, int anchorID2 = -1)
 {
     DiagramID   = Program.DForm.CurrentDiagram.NextFreeID();
     X1          = x1;
     Y1          = y1;
     X2          = x2;
     Y2          = y2;
     Thickness   = thickness;
     Colour      = (colour == null) ? DefaultColour : colour.Value;
     TypeOfBond  = typeOfBond;
     BondSubtype = subtype;
     AnchorID1   = anchorID1;
     AnchorID2   = anchorID2;
 }
Exemplo n.º 9
0
        private static HandleIcon GetHandleIcon(BondType bt, TransformKind tk)
        {
            HandleIcon result;

            switch (bt)
            {
            case BondType.Handle:
                result = (tk == Enums.TransformKind.Scale) ? HandleIcon.Handle : HandleIcon.Rotate;
                break;

            case BondType.Join:
                result = HandleIcon.Join;
                break;

            case BondType.Anchor:
                result = HandleIcon.Anchor;
                break;

            case BondType.Lock:
                result = HandleIcon.Lock;
                break;

            case BondType.Pin:
                result = HandleIcon.Pin;
                break;

            case BondType.Spring:
                result = HandleIcon.Spring;
                break;

            default:
                result = HandleIcon.Handle;
                break;
            }

            return(result);
        }
Exemplo n.º 10
0
    public void GetBondTypesFromXML()
    {
        string path = "Assets/Resources/Data/Bonds.xml";

        bondTypesDict = new Dictionary <string, BondType> ();

        XDocument bondsX = FileIO.ReadXML(path);

        XElement atomsX = bondsX.Element("elements");

        string atomElement;
        string otherElement;
        string a0El;
        string a1El;

        foreach (XElement atomEl in atomsX.Elements("atom"))
        {
            atomElement = atomEl.Attribute("element").Value;

            foreach (XElement otherEl in atomEl.Elements("other"))
            {
                otherElement = otherEl.Attribute("element").Value;
                BondType bondType = new BondType();

                XElement singleEl = otherEl.Element("single");
                if (singleEl != null)
                {
                    bondType.singleThresh = float.Parse(singleEl.Value);
                }

                XElement aromaticEl = otherEl.Element("aromatic");
                if (aromaticEl != null)
                {
                    bondType.aromaticThresh = float.Parse(aromaticEl.Value);
                }

                XElement doubleEl = otherEl.Element("double");
                if (doubleEl != null)
                {
                    bondType.doubleThresh = float.Parse(doubleEl.Value);
                }

                XElement tripleEl = otherEl.Element("triple");
                if (tripleEl != null)
                {
                    bondType.tripleThresh = float.Parse(tripleEl.Value);
                }

                a0El = string.Compare(atomElement, otherElement) > 0 ? atomElement : otherElement;
                a1El = string.Compare(atomElement, otherElement) > 0 ? otherElement : atomElement;
                string key = string.Format("{0}-{1}", a0El, a1El);

                if (bondTypesDict.ContainsKey(key))
                {
                    Debug.LogErrorFormat("Duplicate exists in XML file: {0} ({1})", path, key);
                }
                else
                {
                    bondTypesDict.Add(key, bondType);
                }
            }
        }
    }
Exemplo n.º 11
0
 public Bond(BondType type)
 {
     Id               = Guid.NewGuid();
     Type             = type;
     isPriceAvailable = false;
 }
Exemplo n.º 12
0
 public static void DoBond(BondType bondType, Reactor reactor, bool forRed)
 {
     foreach (PotentialBond potentialBond in GetPotentialBonds(reactor, bondType))
     {
         Molecule molecule1 = reactor.moleculeList.getMoleculeAtCoords(potentialBond.coords);
         Molecule molecule2 = reactor.moleculeList.getMoleculeAtCoords(potentialBond.getCoordsOfOtherBonder());
         if (molecule1 != null && molecule2 != null)
         {
             MoleculeDefinition resultMolecule = molecule1.GetTransformedDefinition(Vector2i.NULL);
             if (bondType == BondType.Plus)
             {
                 if (molecule1 != molecule2)
                 {
                     resultMolecule.CopyAtomsAndBonds(molecule2.GetTransformedDefinition(Vector2i.NULL));
                 }
                 BondCount numBonds = (BondCount)1;
                 // Math.Min(atom.bondCount(potentialBond).Value + 1, 3)
                 // aka increase bonds by 1 but not more than 3
                 if (resultMolecule.GetBondCount(potentialBond).HasValue)
                 {
                     numBonds = (BondCount)Math.Min((int)(resultMolecule.GetBondCount(potentialBond).Value + 1), 3);
                 }
                 if (resultMolecule.SetBondCountWithMaxBondsCheck(potentialBond, numBonds))
                 {
                     reactor.moleculeList.Remove(molecule1);
                     if (molecule1 != molecule2)
                     {
                         reactor.moleculeList.Remove(molecule2);
                     }
                     reactor.moleculeList.Add(new Molecule(resultMolecule, reactor));
                     reactor.AddBondEffect((potentialBond.coords + potentialBond.getCoordsOfOtherBonder()) * 0.5f, BondEffectStyle.Plus, forRed);
                 }
                 else
                 {
                     reactor.AddBondEffect((potentialBond.coords + potentialBond.getCoordsOfOtherBonder()) * 0.5f, BondEffectStyle.MaxBonds, forRed);
                     // The next line is the only change in this method, and should fix the telekinesis bug.
                     // If both waldos hold the same molecule and we allow execution to continue to the next foreach,
                     // the following would happen:
                     // 1. The pull vectors of the molecule are cleared.
                     // 2. The red waldo adds itself to the molecule's pull vectors in GrabDrop().
                     // 3. The pull vectors of the molecule are cleared _again_, removing the red waldo.
                     // 4. The blue waldo adds itself to the molecule's pull vectors in GrabDrop().
                     // The end result is that the game thinks only blue is holding the molecule, triggering the telekinesis bug.
                     // It's safe to skip this foreach since hitting max bonds means no molecule was changed and the current pull vectors are still OK.
                     continue;
                 }
             }
             // bondType != BondType.Plus
             else if (molecule1 == molecule2 && resultMolecule.GetBondCount(potentialBond).HasValue)
             {
                 reactor.moleculeList.Remove(molecule1);
                 int newBondCount = (int)(resultMolecule.GetBondCount(potentialBond).Value - 1);
                 if (newBondCount < 1)
                 {
                     foreach (MoleculeDefinition newMolecule in MoleculeDefinition.BreakBond(resultMolecule, potentialBond))
                     {
                         reactor.moleculeList.Add(new Molecule(newMolecule, reactor));
                     }
                 }
                 else
                 {
                     resultMolecule.SetBondCount(potentialBond, new BondCount?((BondCount)newBondCount));
                     reactor.moleculeList.Add(new Molecule(resultMolecule, reactor));
                 }
                 reactor.AddBondEffect((potentialBond.coords + potentialBond.getCoordsOfOtherBonder()) * 0.5f, BondEffectStyle.Minus, forRed);
             }
             else
             {
                 continue;
             }
             foreach (Waldo waldo in reactor.waldos.Values)
             {
                 if (waldo.molecule != null)
                 {
                     waldo.molecule.WaldoPullVectors.Clear();
                     waldo.molecule = null;
                     waldo.GrabDrop();
                 }
             }
         }
     }
     if (isBonderFeatureCache == null)
     {
         isBonderFeatureCache = new Func <ReactorMember, bool>(IsBonderFeature);
     }
     foreach (BonderFeature bonderFeature in reactor.GetMembers().Where(isBonderFeatureCache).Cast <BonderFeature>())
     {
         bonderFeature.Activate(forRed);
     }
 }
Exemplo n.º 13
0
 public static LinkedList <PotentialBond> GetPotentialBonds(Reactor reactor, BondType bondType)
 {
     return(null);
 }
Exemplo n.º 14
0
 public BondInstruction(Reactor reactor, BondType bondType)
 {
 }
Exemplo n.º 15
0
    /// <summary>根据DisplayMode创建整个蛋白质模型 </summary>
    public void CreateProtein(Protein protein, DisplayMode displayMode)
    {
        Vector3 initPos = Vector3.zero;

        //若之前已创建Protein 则继承原来的位置 否则在摄像机的前2米初始化
        if (proteinDisplayerGo != null)
        {
            initPos = proteinDisplayerGo.transform.position;
        }
        else
        {
            Camera mainCamera = Camera.main;
            initPos = mainCamera.transform.position + oriOffsetToMainCamera.z * mainCamera.transform.forward
                      + oriOffsetToMainCamera.y * mainCamera.transform.up + oriOffsetToMainCamera.x * mainCamera.transform.right;
        }

        proteinDisplayerGo      = Instantiate(proteinTemplatePrefeb, Displayer3DRoot.transform, true);
        proteinDisplayerGo.name = protein.ID;
        proteinDisplayerGo.GetComponent <ProteinDisplayer>().Protein = protein;
        foreach (var chainKvp in protein.Chains)
        {
            Chain      chain            = chainKvp.Value;
            GameObject chainDisplayerGo = new GameObject(chain.ID, typeof(ChainDisplayer));
            chainDisplayerGo.GetComponent <ChainDisplayer>().Chain = chain;
            chainDisplayerGo.transform.SetParent(proteinDisplayerGo.transform);
            //创建每个原子模型
            foreach (var aminoacidKvp in chain.SeqAminoacids)
            {
                AminoacidInProtein aminoacidInProtein = aminoacidKvp.Value;
                //GameObject aminoacidDisplayerGo = new GameObject(aminoacidInProtein.ResidueSeq.ToString(), typeof(AminoacidDisplayer));
                GameObject aminoacidDisplayerGo = Instantiate <GameObject>(residueTemplatePrefeb, chainDisplayerGo.transform);
                aminoacidDisplayerGo.name = aminoacidInProtein.ResidueSeq.ToString();
                AminoacidDisplayer aminoacidDisplayer = aminoacidDisplayerGo.GetComponent <AminoacidDisplayer>();
                aminoacidDisplayer.AminoacidInProtein = aminoacidInProtein;

                //棍状模型不显示原子球
                if (displayMode != DisplayMode.Sticks)
                {
                    foreach (var atomKvp in aminoacidInProtein.AtomInAminoacidSerial)
                    {
                        AtomInAminoacid atomInAminoacid       = atomKvp.Key;
                        GameObject      atomDisplayerGoPrefeb = GetAtomPrefeb(atomInAminoacid.Aminoacid.Type);
                        switch (displayMode)
                        {
                        case DisplayMode.Spacefill: atomDisplayerGoPrefeb.transform.localScale = new Vector3(AtomFillSize, AtomFillSize, AtomFillSize); break;

                        case DisplayMode.BallStick: atomDisplayerGoPrefeb.transform.localScale = new Vector3(AtomBallStickSize, AtomBallStickSize, AtomBallStickSize); break;

                        default: throw new System.Exception(string.Format("Unhandled displayMode: {0}", displayMode));
                        }
                        GameObject atomDisplayerGo = Instantiate(atomDisplayerGoPrefeb, aminoacidDisplayerGo.transform, false);
                        atomDisplayerGo.name = atomInAminoacid.Name;
                        atomDisplayerGo.transform.localPosition = (aminoacidInProtein.AtomInAminoacidPos[atomInAminoacid] - protein.CenterPos) * BallStickPosScale;
                        AtomDisplayer atomDisplayer = atomDisplayerGo.GetComponent <AtomDisplayer>();
                        atomDisplayer.AtomInAminoacid    = atomInAminoacid;
                        atomDisplayer.AminoacidInProtein = aminoacidInProtein;
                    }
                }
                //创建每个键的模型
                if (displayMode == DisplayMode.BallStick || displayMode == DisplayMode.Sticks)
                {
                    AminoacidInProtein lastAminoacidInProtein = null;
                    //若在该链存在上一序列号的残基 则构造一个该残基的N连通上一残基的C形成的肽键
                    if (aminoacidInProtein.Chain.SeqAminoacids.TryGetValue(aminoacidInProtein.ResidueSeq - 1, out lastAminoacidInProtein))
                    {
                        //两个Bond 两个颜色
                        string        name1          = string.Format("{0}-{1}-Peptidebond", lastAminoacidInProtein.ResidueSeq, aminoacidInProtein.ResidueSeq);
                        string        name2          = string.Format("{0}-{1}-Peptidebond", aminoacidInProtein.ResidueSeq, lastAminoacidInProtein.ResidueSeq);
                        Vector3       pos1           = (lastAminoacidInProtein.AtomInAminoacidPos[lastAminoacidInProtein.Aminoacid["C"]] - protein.CenterPos) * BallStickPosScale;
                        Vector3       pos3           = (aminoacidInProtein.AtomInAminoacidPos[aminoacidInProtein.Aminoacid["N"]] - protein.CenterPos) * BallStickPosScale;
                        Vector3       pos2           = (pos1 + pos3) / 2;
                        BondType      bondType       = BondType.Single;
                        Transform     parent         = aminoacidDisplayerGo.transform;
                        AminoacidType aminoacidType1 = lastAminoacidInProtein.Aminoacid.Type;
                        AminoacidType aminoacidType2 = aminoacidInProtein.Aminoacid.Type;
                        GenerateBondGameObject(name1, pos1, pos2, bondType, parent, aminoacidType1, displayMode);
                        GenerateBondGameObject(name2, pos2, pos3, bondType, parent, aminoacidType2, displayMode);
                    }
                    //氨基酸内的化学键(从本地Aminoacid数据中获取的连接关系)
                    foreach (var connection in aminoacidInProtein.Aminoacid.Connections)
                    {
                        string  name = string.Format("{0}-{1}-bond", connection.Key.Key.Name, connection.Key.Value.Name);
                        Vector3 pos1 = Vector3.zero; Vector3 pos2 = Vector3.zero;
                        //若读取的pdb文件中的某残基中没有连接关系中的某个原子 说明源pdb文件出现数据遗漏
                        try {
                            pos1 = (aminoacidInProtein.AtomInAminoacidPos[connection.Key.Key] - protein.CenterPos) * BallStickPosScale;
                            pos2 = (aminoacidInProtein.AtomInAminoacidPos[connection.Key.Value] - protein.CenterPos) * BallStickPosScale;
                        }
                        catch (KeyNotFoundException ex) {
                            //Debug.LogWarning(string.Format("The aminoacidInProtein: {0} is not complete, the atom in connection: {1}-{2} is losed", aminoacidInProtein, connection.Key.Key.Name, connection.Key.Value.Name));
                            continue;
                        }
                        BondType      bondType      = connection.Value;
                        Transform     parent        = aminoacidDisplayerGo.transform;
                        AminoacidType aminoacidType = aminoacidInProtein.Aminoacid.Type;
                        GenerateBondGameObject(name, pos1, pos2, bondType, parent, aminoacidType, displayMode);
                    }
                }
                //若合并Mesh 在Residue的mesh合并渲染 所有子物体不渲染
                if (conbineMesh)
                {
                    MeshFilter   residueMeshFilter   = aminoacidDisplayerGo.AddComponent <MeshFilter>();
                    MeshRenderer residueMeshRenderer = aminoacidDisplayerGo.AddComponent <MeshRenderer>();
                    residueMeshFilter.sharedMesh       = aminoacidDisplayerGo.transform.CombineChildsMesh();
                    residueMeshRenderer.sharedMaterial = GetMaterial(aminoacidInProtein.Aminoacid.Type);
                    MeshRenderer[] childMeshRenderers = aminoacidDisplayerGo.GetComponentsInChildren <MeshRenderer>();
                    foreach (var renderer in childMeshRenderers)
                    {
                        renderer.enabled = false;
                    }
                    residueMeshRenderer.enabled  = true;
                    aminoacidDisplayer.Normal    = GetMaterial(aminoacidInProtein.Aminoacid.Type);
                    aminoacidDisplayer.HighLight = GetHighlightMaterial(aminoacidInProtein.Aminoacid.Type);
                }
            }
        }
        proteinDisplayerGo.transform.localScale = new Vector3(0.2f, 0.2f, 0.2f); //缩放0.2倍
        proteinDisplayerGo.transform.position   = initPos;
    }
Exemplo n.º 16
0
        //static Molecule ReadMoleFile(string filename)
        //{
        //    using (var reader = new System.IO.StreamReader(filename))
        //    {
        //        string s = reader.ReadToEnd();
        //        if (s.Contains("V2000")) return MoleFileReader.ParseMoleFile2(s);
        //        if (s.Contains("V3000")) throw new Exception("Version 3000 Mol file is currently not supported.");
        //        throw new Exception("Mol file type not recognized. It is does not contain a version number.");
        //    }
        //}

        static Molecule ParseMoleFile2(string moleFile)
        {
            Molecule molecule = new Molecule();
            //atoms.Clear();
            //cycles.Clear();
            //fusedRings.Clear();

            int numAtoms = 0;
            int numBonds = 0;

            // This information is contained in the header (first 3 lines) of the mol file. It is currently not being used, but code has been created for
            // future use.
            string name    = string.Empty;
            string program = string.Empty;
            string user    = string.Empty;
            //// used to test Line 2 reading below.
            //string MM = string.Empty;
            //string DD = string.Empty;
            //string YY = string.Empty;
            //string HH = string.Empty;
            //string mm = string.Empty;
            int    MM = 1;
            int    DD = 1;
            int    YY = 0;
            int    HH = 0;
            int    mm = 0;
            string dimensionalCodes = string.Empty;
            //// used to test Line 2 reading below.
            //string scalingFactor1 = string.Empty;
            int scalingFactor1 = 0;
            //// used to test Line 2 reading below.
            //string scalingFactor2 = string.Empty;
            double scalingFactor2 = 0;
            // used to test Line 2 reading below.
            string energy         = string.Empty;
            string registryNumber = string.Empty;
            string comments       = string.Empty;

            string[] lines = moleFile.Split('\n');
            // Line 1 contains the compound name. It can not be longer than 80 characters, and is allowed to be empty.
            // The length of the line is not relevant in how this is read, so it is not checked.
            name = lines[0];
            //// used to test Line 2 reading below.
            //lines[1] = "IIPPPPPPPPMMDDYYHHmmddSSssssssssssEEEEEEEEEEEERRRRRR";
            // Line 2 is optional. Skip this if it is not there.
            if (lines[1] != string.Empty)
            {
                // Line format: IIPPPPPPPPMMDDYYHHmmddSSssssssssssEEEEEEEEEEEERRRRRR
                //              A2<--A8--><---A10-->A2I2<--F10.5-><---F12.5--><-I6->
                //User's first and last initials (l), program name (P), date/time (M/D/Y,H:m),
                //dimensional codes (d), scaling factors (S, s), energy (E) if modeling program input,
                //internal registry number (R) if input through MDL form.
                if (lines[1].Length > 2)
                {
                    user = lines[1].Substring(0, 2);                      // II
                }
                if (lines[1].Length > 10)
                {
                    program = lines[1].Substring(2, 8);                       // PPPPPPPP
                }
                if (lines[1].Length > 20)
                {
                    //// used to test Line 2 reading below.
                    //MM = lines[1].Substring(10, 2); // MMDDYYHHmm
                    //DD = lines[1].Substring(12, 2); // MMDDYYHHmm
                    //YY = lines[1].Substring(14, 2); // MMDDYYHHmm
                    //HH = lines[1].Substring(16, 2); // MMDDYYHHmm
                    //mm = lines[1].Substring(18, 2); // MMDDYYHHmm
                    MM = Convert.ToInt32(lines[1].Substring(10, 2)); // MMDDYYHHmm
                    DD = Convert.ToInt32(lines[1].Substring(12, 2)); // MMDDYYHHmm
                    YY = Convert.ToInt32(lines[1].Substring(14, 2)); // MMDDYYHHmm
                    HH = Convert.ToInt32(lines[1].Substring(16, 2)); // MMDDYYHHmm
                    mm = Convert.ToInt32(lines[1].Substring(18, 2)); // MMDDYYHHmm
                }
                if (lines[1].Length > 22)
                {
                    dimensionalCodes = lines[1].Substring(20, 2);                       // dd
                }
                //// used to test Line 2 reading below.
                // if (lines[1].Length > 24) scalingFactor1 = lines[1].Substring(22, 2); //SS
                if (lines[1].Length > 24)
                {
                    scalingFactor1 = Convert.ToInt32(lines[1].Substring(22, 2));                       //SS
                }
                //// used to test Line 2 reading below.
                // if (lines[1].Length > 34) scalingFactor2 = lines[1].Substring(24, 10); //ss
                if (lines[1].Length > 34)
                {
                    scalingFactor2 = Convert.ToDouble(lines[1].Substring(24, 10));                       //ss
                }
                if (lines[1].Length > 46)
                {
                    energy = lines[1].Substring(34, 12);                       //EEEEEEEEEEEE
                }
                if (lines[1].Length == 52)
                {
                    registryNumber = lines[1].Substring(46, 6);                        //RRRRRR
                }
            }
            comments = lines[2];

            // Counts Line
            // aaabbblllfffcccsssxxxrrrpppiiimmmvvvvvv
            numAtoms = Convert.ToInt32(lines[3].Substring(0, 3));
            numBonds = Convert.ToInt32(lines[3].Substring(3, 3));
            int atomLists = Convert.ToInt32(lines[3].Substring(6, 3));
            //int fObsolete = Convert.ToInt32(lines[3].Substring(9, 3));
            bool chiral = false;

            if (Convert.ToInt32(lines[3].Substring(12, 3)) == 1)
            {
                chiral = true;
            }
            int sText = Convert.ToInt32(lines[3].Substring(15, 3));
            //int xObsolete = Convert.ToInt32(lines[3].Substring(18, 3));
            //int rObsolete = Convert.ToInt32(lines[3].Substring(21, 3));
            //int pObsolete = Convert.ToInt32(lines[3].Substring(24, 3));
            //int iObsolete = Convert.ToInt32(lines[3].Substring(27, 3));
            int    properties = Convert.ToInt32(lines[3].Substring(30, 3));
            string version    = lines[3].Substring(33, 6);

            for (int i = 0; i < numAtoms; i++)
            {
                Atom a = new ChemInfo.Atom(lines[4 + i].Substring(31, 3).Trim());
                molecule.AddAtom(a);
                // xxxxx.xxxxyyyyy.yyyyzzzzz.zzzz aaaddcccssshhhbbbvvvHHHrrriiimmmnnneee
                //a.x = Convert.ToDouble(lines[4 + i].Substring(0, 10));
                //a.y = Convert.ToDouble(lines[4 + i].Substring(10, 10));
                //a.z = Convert.ToDouble(lines[4 + i].Substring(20, 10));
                string text = lines[4 + i].Substring(34, 2);
                a.MassDiff      = Convert.ToInt32(lines[4 + i].Substring(34, 2));
                a.Charge        = Convert.ToInt32(lines[4 + i].Substring(36, 3));
                a.StereoParity  = Convert.ToInt32(lines[4 + i].Substring(39, 3));
                a.HydrogenCount = Convert.ToInt32(lines[4 + i].Substring(42, 3));
                a.StereoCareBox = Convert.ToInt32(lines[4 + i].Substring(45, 3));
                //a.Valence = Convert.ToInt32(lines[4 + i].Substring(48, 3));
                // string H0 = lines[4 + i].Substring(51, 3);
                // a.HO = Convert.ToInt32(lines[4 + i].Substring(51, 3));
                a.RNotUsed           = lines[4 + i].Substring(54, 3);
                a.INotUsed           = lines[4 + i].Substring(57, 3);
                a.AtomMapping        = Convert.ToInt32(lines[4 + i].Substring(60, 3));
                a.InversionRetension = Convert.ToInt32(lines[4 + i].Substring(63, 3));
                a.ExactChange        = Convert.ToInt32(lines[4 + i].Substring(66, 3));
            }
            for (int i = 0; i < numBonds; i++)
            {
                //Bond b = new Bond();
                // 111222tttsssxxxrrrccc
                string                   line           = lines[4 + numAtoms + i];
                int                      firstAtom      = Convert.ToInt32(lines[4 + numAtoms + i].Substring(0, 3));
                int                      secondAtom     = Convert.ToInt32(lines[4 + numAtoms + i].Substring(3, 3));
                BondType                 bondType       = (BondType)Convert.ToInt32(lines[4 + numAtoms + i].Substring(6, 3));
                BondStereo               bondStereo     = (BondStereo)Convert.ToInt32(lines[4 + numAtoms + i].Substring(9, 3));
                string                   xNotUsed       = lines[4 + numAtoms + i].Substring(12, 3);
                BondTopology             bondTopology   = (BondTopology)Convert.ToInt32(lines[4 + numAtoms + i].Substring(15, 3));
                int                      rc             = Convert.ToInt32(lines[4 + numAtoms + i].Substring(18, 3));
                BondReactingCenterStatus reactingCenter = BondReactingCenterStatus.Unmarked;
                if (rc == 13)
                {
                    reactingCenter = BondReactingCenterStatus.bondMadeOrBroken | BondReactingCenterStatus.bondOrderChanges | BondReactingCenterStatus.aCenter;
                }
                else if (rc == 12)
                {
                    reactingCenter = BondReactingCenterStatus.bondMadeOrBroken | BondReactingCenterStatus.bondOrderChanges;
                }
                else if (rc == 9)
                {
                    reactingCenter = BondReactingCenterStatus.bondOrderChanges | BondReactingCenterStatus.aCenter;
                }
                else if (rc == 5)
                {
                    reactingCenter = BondReactingCenterStatus.bondMadeOrBroken | BondReactingCenterStatus.aCenter;
                }
                else
                {
                    reactingCenter = (BondReactingCenterStatus)rc;
                }
                molecule.AddBond(molecule.Atoms[firstAtom - 1], molecule.Atoms[secondAtom - 1], bondType, bondStereo, bondTopology, reactingCenter);
            }
            molecule.FindRings();
            return(molecule);
        }
Exemplo n.º 17
0
 public Bond(uint sourceInstanceId, BondAttachment sourceAttachment, BondType bondType)
 {
     this.sourceInstanceId = sourceInstanceId;
     this.sourceAttachment = sourceAttachment;
     this.bondType = bondType;
 }
Exemplo n.º 18
0
        private bool RemoveCollidingBond(uint instanceId, BondAttachment attachment, List <Bond> previousBonds, BondType newBondType)
        {
            bool result = true;

            if (!attachment.IsGuide() && bonds.ContainsKey(instanceId))
            {
                Bond cb = null;
                foreach (Bond b in bonds[instanceId])
                {
                    cb = b.GetCollidingBond(attachment);
                    if (cb != null)
                    {
                        break;
                    }
                }

                if (cb != null)
                {
                    bool oldIsFlow = cb.ChainType != ChainType.None;
                    bool newIsLock = newBondType == BondType.Lock;
                    // locks can't break flow bonds
                    if (oldIsFlow && newIsLock)
                    {
                        result = false;
                    }
                    else
                    {
                        RemoveBond(cb);
                        previousBonds.Add(cb);
                    }
                }
            }
            return(result);
        }
Exemplo n.º 19
0
    //这里的position是真正坐标而不是pdb文件中读取的坐标
    /// <summary>创建键</summary>
    private GameObject GenerateBondGameObject(string name, Vector3 pos1, Vector3 pos2, BondType bondType, Transform parent, AminoacidType aminoacidType, DisplayMode displayMode)
    {
        GameObject bondGo             = null;
        Material   material           = GetMaterial(aminoacidType);
        Material   hightLightMaterial = GetHighlightMaterial(aminoacidType);
        float      bondLength         = (pos1 - pos2).magnitude;  //键长
        Vector3    bondDirection      = (pos1 - pos2).normalized; //键方向

        //Sticks模式只创建单键
        if (bondType == BondType.Single || displayMode == DisplayMode.Sticks)
        {
            bondGo = Instantiate(SingleBondPrefeb, parent, false);
        }
        else if (bondType == BondType.Double)
        {
            bondGo = Instantiate(DoubleBondPrefeb, parent, false);
        }
        else
        {
            throw new System.Exception("Unhandled bondType :" + bondType);
        }

        BondDisplayer bondDisplayer = bondGo.GetComponent <BondDisplayer>();

        bondDisplayer.BondType  = bondType;
        bondDisplayer.normal    = material;
        bondDisplayer.highLight = hightLightMaterial;

        bondGo.name = name;
        foreach (Transform child in bondGo.transform)
        {
            child.GetComponent <Renderer>().material = material;
        }
        bondGo.transform.localPosition = (pos1 + pos2) / 2;
        bondGo.transform.localScale    = new Vector3(0.01f, 0.01f, bondLength / 2);
        Vector3 targetPos = Vector3.Cross(bondDirection, Vector3.up) + (pos1 + pos2) / 2;

        bondGo.transform.LookAt(pos1);
        return(bondGo);
    }
Exemplo n.º 20
0
    public void ShowProtein(Protein protein)
    {
        GameObject proteinDisplayerGo = new GameObject(protein.ID, typeof(ProteinDisplayer));

        proteinDisplayerGo.GetComponent <ProteinDisplayer>().Protein = protein;

        Displayer3DRoot.transform.localPosition = Vector3.zero;
        Displayer3DRoot.transform.localRotation = Quaternion.identity;
        Displayer3DRoot.transform.localScale    = new Vector3(1, 1, 1);
        proteinDisplayerGo.transform.SetParent(Displayer3DRoot.transform);

        foreach (var chainKvp in protein.Chains)
        {
            Chain      chain            = chainKvp.Value;
            GameObject chainDisplayerGo = new GameObject(chain.ID, typeof(ChainDisplayer));
            chainDisplayerGo.GetComponent <ChainDisplayer>().Chain = chain;
            chainDisplayerGo.transform.SetParent(proteinDisplayerGo.transform);
            //创建每个原子模型
            foreach (var aminoacidKvp in chain.SeqAminoacids)
            {
                AminoacidInProtein aminoacidInProtein   = aminoacidKvp.Value;
                GameObject         aminoacidDisplayerGo = new GameObject(aminoacidInProtein.ResidueSeq.ToString(), typeof(AminoacidDisplayer));
                aminoacidDisplayerGo.GetComponent <AminoacidDisplayer>().AminoacidInProtein = aminoacidInProtein;
                aminoacidDisplayerGo.transform.SetParent(chainDisplayerGo.transform);
                foreach (var atomKvp in aminoacidInProtein.AtomInAminoacidSerial)
                {
                    AtomInAminoacid atomInAminoacid       = atomKvp.Key;
                    GameObject      atomDisplayerGoPrefeb = GetAtomPrefeb(atomInAminoacid.Aminoacid.Type);
                    switch (displayMode)
                    {
                    case DisplayMode.Spacefill: atomDisplayerGoPrefeb.transform.localScale = new Vector3(AtomFillSize, AtomFillSize, AtomFillSize); break;

                    case DisplayMode.BallStick: atomDisplayerGoPrefeb.transform.localScale = new Vector3(AtomBallStickSize, AtomBallStickSize, AtomBallStickSize); break;

                    case DisplayMode.Stick: atomDisplayerGoPrefeb.transform.localScale = new Vector3(AtomStickSize, AtomStickSize, AtomStickSize); break;

                    default: throw new System.Exception(string.Format("Unhandled displayMode: {0}", displayMode));
                    }
                    GameObject atomDisplayerGo = Instantiate(atomDisplayerGoPrefeb, aminoacidDisplayerGo.transform, false);
                    atomDisplayerGo.name = atomInAminoacid.Name;
                    atomDisplayerGo.transform.localPosition = (aminoacidInProtein.AtomInAminoacidPos[atomInAminoacid] - protein.CenterPos) * BallStickPosScale;
                    AtomDisplayer atomDisplayer = atomDisplayerGo.GetComponent <AtomDisplayer>();
                    atomDisplayer.AtomInAminoacid    = atomInAminoacid;
                    atomDisplayer.AminoacidInProtein = aminoacidInProtein;
                }
                //创建每个键的模型
                if (displayMode == DisplayMode.BallStick || displayMode == DisplayMode.Stick)
                {
                    AminoacidInProtein lastAminoacidInProtein = null;
                    //若在该链存在上一序列号的残基 则构造一个该残基的N连通上一残基的C形成的肽键
                    if (aminoacidInProtein.Chain.SeqAminoacids.TryGetValue(aminoacidInProtein.ResidueSeq - 1, out lastAminoacidInProtein))
                    {
                        //两个Bond 两个颜色
                        string        name1          = string.Format("{0}-{1}-Peptidebond", lastAminoacidInProtein.ResidueSeq, aminoacidInProtein.ResidueSeq);
                        string        name2          = string.Format("{0}-{1}-Peptidebond", aminoacidInProtein.ResidueSeq, lastAminoacidInProtein.ResidueSeq);
                        Vector3       pos1           = (lastAminoacidInProtein.AtomInAminoacidPos[lastAminoacidInProtein.Aminoacid["C"]] - protein.CenterPos) * BallStickPosScale;
                        Vector3       pos3           = (aminoacidInProtein.AtomInAminoacidPos[aminoacidInProtein.Aminoacid["N"]] - protein.CenterPos) * BallStickPosScale;
                        Vector3       pos2           = (pos1 + pos3) / 2;
                        BondType      bondType       = BondType.Single;
                        Transform     parent         = aminoacidDisplayerGo.transform;
                        AminoacidType aminoacidType1 = lastAminoacidInProtein.Aminoacid.Type;
                        AminoacidType aminoacidType2 = aminoacidInProtein.Aminoacid.Type;
                        GenerateBondGameObject(name1, pos1, pos2, bondType, parent, aminoacidType1);
                        GenerateBondGameObject(name2, pos2, pos3, bondType, parent, aminoacidType2);
                    }
                    //氨基酸内的化学键(从本地Aminoacid数据中获取的连接关系)
                    foreach (var connection in aminoacidInProtein.Aminoacid.Connections)
                    {
                        string  name = string.Format("{0}-{1}-bond", connection.Key.Key.Name, connection.Key.Value.Name);
                        Vector3 pos1 = Vector3.zero; Vector3 pos2 = Vector3.zero;
                        //若读取的pdb文件中的某残基中没有连接关系中的某个原子 说明源pdb文件出现数据遗漏
                        try
                        {
                            pos1 = (aminoacidInProtein.AtomInAminoacidPos[connection.Key.Key] - protein.CenterPos) * BallStickPosScale;
                            pos2 = (aminoacidInProtein.AtomInAminoacidPos[connection.Key.Value] - protein.CenterPos) * BallStickPosScale;
                        }
                        catch (KeyNotFoundException)
                        {
                            //Debug.LogWarning(string.Format("The aminoacidInProtein: {0} is not complete, the atom in connection: {1}-{2} is losed", aminoacidInProtein, connection.Key.Key.Name, connection.Key.Value.Name));
                            continue;
                        }
                        BondType      bondType      = connection.Value;
                        Transform     parent        = aminoacidDisplayerGo.transform;
                        AminoacidType aminoacidType = aminoacidInProtein.Aminoacid.Type;
                        GenerateBondGameObject(name, pos1, pos2, bondType, parent, aminoacidType);
                    }
                }
            }
        }
    }
Exemplo n.º 21
0
 public Bond(uint sourceInstanceId, BondAttachment sourceAttachment, BondType bondType)
 {
     this.sourceInstanceId = sourceInstanceId;
     this.sourceAttachment = sourceAttachment;
     this.bondType         = bondType;
 }
Exemplo n.º 22
0
 public Bond(Node thisNode, Node thatNode, BondType t)
 {
     Node1 = thisNode;
     Node2 = thatNode;
     Type  = t;
 }
Exemplo n.º 23
0
        //public override object VisitBracket_atom(smilesParser.Bracket_atomContext context)
        //{
        //    string symbol = string.Empty;
        //    Chirality ch = Chirality.UNSPECIFIED;
        //    int isotope = 0;
        //    int hCount = 0;
        //    int charge = 0;
        //    int atomClass = 0;
        //    foreach (IParseTree tree in context.children)
        //    {
        //        if (typeof(smilesParser.SymbolContext).IsAssignableFrom(tree.GetType()))
        //        {
        //            symbol = (string)VisitSymbol((smilesParser.SymbolContext)tree);
        //        }
        //        if (typeof(smilesParser.ChiralContext).IsAssignableFrom(tree.GetType()))
        //        {
        //            ch = (Chirality)VisitChiral((smilesParser.ChiralContext)tree);
        //        }
        //        if (typeof(smilesParser.IsotopeContext).IsAssignableFrom(tree.GetType()))
        //        {
        //            isotope = (int)VisitIsotope((smilesParser.IsotopeContext)tree);
        //        }
        //        if (typeof(smilesParser.HcountContext).IsAssignableFrom(tree.GetType()))
        //        {
        //            hCount = (int)VisitHcount((smilesParser.HcountContext)tree);
        //        }
        //        if (typeof(smilesParser.ChargeContext).IsAssignableFrom(tree.GetType()))
        //        {
        //            charge = (int)VisitCharge((smilesParser.ChargeContext)tree);
        //        }
        //        if (typeof(smilesParser.AtomclassContext).IsAssignableFrom(tree.GetType()))
        //        {
        //            atomClass = (int)VisitAtomclass((smilesParser.AtomclassContext)tree);
        //        }
        //    }
        //    return new Atom(symbol, AtomType.NONE, isotope, ch, hCount, charge, atomClass);
        //}

        public override object VisitBranch([NotNull] smilesParser.BranchContext context)
        {
            if (context.ChildCount == 3)
            {
                if (typeof(smilesParser.ChainContext).IsAssignableFrom(context.GetChild(1).GetType()))
                {
                    return(VisitChain((smilesParser.ChainContext)context.GetChild(1)));
                }
                return(VisitBranch((smilesParser.BranchContext)context.GetChild(1)));
            }
            if (typeof(smilesParser.BondContext).IsAssignableFrom(context.GetChild(1).GetType()))
            {
                if (context.GetChild(1).GetText() == "\\")
                {
                    if (string.IsNullOrEmpty(cisTrans))
                    {
                        cisTrans = "/";
                    }
                    else
                    {
                        if (context.GetText() == cisTrans)
                        {
                            if (((doubleBonds.Count - 1) % 2) == 0)
                            {
                                foreach (Bond b in doubleBonds)
                                {
                                    b.Stereo = BondStereo.cis;
                                }
                            }
                        }
                        else
                        {
                            if (((doubleBonds.Count - 1) % 2) == 0)
                            {
                                foreach (Bond b in doubleBonds)
                                {
                                    b.Stereo = BondStereo.trans;
                                }
                            }
                        }
                        cisTrans = string.Empty;
                        doubleBonds.Clear();
                    }
                }
                else if (context.GetChild(1).GetText() == "/")
                {
                    if (string.IsNullOrEmpty(cisTrans))
                    {
                        cisTrans = "\\";
                    }
                    else
                    {
                        if (context.GetText() == cisTrans)
                        {
                            if (((doubleBonds.Count - 1) % 2) == 0)
                            {
                                foreach (Bond b in doubleBonds)
                                {
                                    b.Stereo = BondStereo.cis;
                                }
                            }
                        }
                        else
                        {
                            if (((doubleBonds.Count - 1) % 2) == 0)
                            {
                                foreach (Bond b in doubleBonds)
                                {
                                    b.Stereo = BondStereo.trans;
                                }
                            }
                        }
                        cisTrans = string.Empty;
                        doubleBonds.Clear();
                    }
                }
                else
                {
                    nextBond = (BondType)VisitBond((smilesParser.BondContext)context.GetChild(1));
                }
                return(VisitChain((smilesParser.ChainContext)context.GetChild(2)));
            }
            nextBond = (BondType)VisitDot((smilesParser.DotContext)context.GetChild(1));
            return(VisitChain((smilesParser.ChainContext)context.GetChild(2)));
        }
Exemplo n.º 24
0
 public override object VisitBranched_atom([NotNull] smilesParser.Branched_atomContext context)
 {
     foreach (IParseTree tree in context.children)
     {
         if (typeof(smilesParser.AtomContext).IsAssignableFrom(tree.GetType()))
         {
             Atom current = (Atom)VisitAtom((smilesParser.AtomContext)tree);
             if (current.Element != ELEMENTS.H)
             {
                 retVal.AddAtom(current);
                 if (addExplicitHToNext)
                 {
                     current.ExplicitHydrogens++;
                     addExplicitHToNext = false;
                 }
                 if (last != null)
                 {
                     if (last.AtomType == AtomType.AROMATIC && current.AtomType == AtomType.AROMATIC)
                     {
                         nextBond = BondType.Aromatic;
                     }
                 }
                 Bond b = retVal.AddBond(last, current, nextBond, BondStereo.NotStereoOrUseXYZ, BondTopology.Either, BondReactingCenterStatus.Unmarked);
                 if (!string.IsNullOrEmpty(cisTrans) && nextBond == BondType.Double)
                 {
                     doubleBonds.Add(b);
                 }
                 nextBond = BondType.Single;
                 last     = current;
             }
             else
             {
                 if (last != null)
                 {
                     last.ExplicitHydrogens++;
                 }
                 else
                 {
                     addExplicitHToNext = true;
                 }
             }
         }
         else if (typeof(smilesParser.RingbondContext).IsAssignableFrom(tree.GetType()))
         {
             int ring = (int)VisitRingbond((smilesParser.RingbondContext)tree);
             if (ringAtoms.ContainsKey(ring))
             {
                 BondType nextType = (BondType)ringbonds[ring];
                 if (nextType != BondType.Single && (nextBond == BondType.Single || nextBond == nextType))
                 {
                     nextBond = nextType;
                 }
                 Bond b = retVal.AddBond(last, (Atom)ringAtoms[ring], nextBond, BondStereo.NotStereoOrUseXYZ, BondTopology.Either, BondReactingCenterStatus.Unmarked);
                 if (!string.IsNullOrEmpty(cisTrans) && nextBond == BondType.Double)
                 {
                     doubleBonds.Add(b);
                 }
                 nextBond = BondType.Single;
                 ringAtoms.Remove(ring);
                 ringbonds.Remove(ring);
             }
             else
             {
                 ringAtoms.Add(ring, last);
                 ringbonds.Add(ring, nextBond);
                 nextBond = BondType.Single;
             }
         }
         else if (typeof(smilesParser.BranchContext).IsAssignableFrom(tree.GetType()))
         {
             Atom temp = last;
             VisitBranch((smilesParser.BranchContext)tree);
             last = temp;
         }
         else if (typeof(smilesParser.BondContext).IsAssignableFrom(tree.GetType()))
         {
             nextBond = (BondType)VisitBond((smilesParser.BondContext)context.GetChild(1));
         }
         else
         {
             throw new System.InvalidOperationException("uhoh");
         }
     }
     return(null);
 }
Exemplo n.º 25
0
    } // End of Awake().

    public void Update()
    {
        Vector3 vectorAtoB = nodeB.transform.position - nodeA.transform.position;

        dirAtoB = vectorAtoB.normalized;
        float bondLength = vectorAtoB.magnitude;


        // The following billboards the bond graphic with the camera.
        Quaternion bondDirection = Quaternion.LookRotation(nodeB.transform.position - nodeA.transform.position);

        bondBillboard.rotation  = bondDirection;
        bondBillboard.position  = nodeA.transform.position + (vectorAtoB * 0.5f);
        bondBillboard.rotation *= Quaternion.AngleAxis(90, Vector3.up);

        Vector3 camRelativePos    = bondBillboard.InverseTransformPoint(Camera.main.transform.position);
        float   arcBillboardAngle = Mathf.Atan2(camRelativePos.z, camRelativePos.y) * Mathf.Rad2Deg;

        bondBillboard.rotation *= Quaternion.AngleAxis(arcBillboardAngle + 90, Vector3.right);

        Vector3 bondBillboardScale = new Vector3(bondLength * signalLink, bondWidth, 1f);

        bondBillboard.localScale = bondBillboardScale;



        // DEBUG - attraction is a constant.
        float attraction = 12.0f;

        nodeA.rigidbody.AddForce(vectorAtoB.normalized * attraction);
        nodeB.rigidbody.AddForce(-vectorAtoB.normalized * attraction);



        // Determine calorie transfer.
        float calorieTransferStrength = attraction * 0.03f;
        float calorieTransfer         = (nodeB.calories - nodeA.calories) * calorieTransferStrength;

        nodeA.caloriesDelta += calorieTransfer;
        nodeB.caloriesDelta += -calorieTransfer;


        // Different effects based on bond type.
        if ((nodeA.nodeType == NodeType.sense) && (nodeB.nodeType == NodeType.control) ||
            (nodeB.nodeType == NodeType.sense) && (nodeA.nodeType == NodeType.control))
        {
            // Signal Bond
            // Sense -> Control
            bondType = BondType.signal;
            bondBillboard.renderer.material = GameManager.graphics.signalBondMat;

            if (nodeA.nodeType == NodeType.sense)
            {
                signalLink = 1;
                if (nodeA.signal > nodeB.synapse)
                {
                    nodeB.synapse = nodeA.signal;
                }
            }
            else
            {
                signalLink = -1;
                if (nodeB.signal > nodeA.synapse)
                {
                    nodeA.synapse = nodeB.signal;
                }
            }
        }
        else
        if ((nodeA.nodeType == NodeType.control) && (nodeB.nodeType == NodeType.muscle) ||
            (nodeB.nodeType == NodeType.control) && (nodeA.nodeType == NodeType.muscle))
        {
            // Synapse bond
            // Control -> Muscle
            bondType = BondType.synapse;
            bondBillboard.renderer.material = GameManager.graphics.synapseBondMat;

            if (nodeA.nodeType == NodeType.control)
            {
                signalLink = 1;
                if (nodeA.synapse > nodeB.thrust)
                {
                    nodeB.thrust = nodeA.synapse;
                }

                nodeB.thrust = Mathf.Clamp(nodeB.thrust, 0.1f, Mathf.Infinity);
                nodeB.rigidbody.AddForce(-vectorAtoB * 10f * nodeB.thrust);
            }
            else
            {
                signalLink = -1;
                if (nodeB.synapse > nodeA.thrust)
                {
                    nodeA.thrust = nodeB.synapse;
                }

                nodeA.thrust = Mathf.Clamp(nodeA.thrust, 0.1f, Mathf.Infinity);
                nodeA.rigidbody.AddForce(vectorAtoB * 10f * nodeA.thrust);
            }
        }
        else
        if ((nodeA.nodeType == NodeType.control) && (nodeB.nodeType == NodeType.control))
        {
            // Synapse propogation bond
            // Control <-> Control
            bondType = BondType.synapsePropogate;
            bondBillboard.renderer.material = GameManager.graphics.synapsePropBondMat;

            if (nodeA.synapse > nodeB.synapse)
            {
                nodeB.synapse = nodeA.synapse;
            }
            else
            {
                nodeA.synapse = nodeB.synapse;
            }
        }
        else
        if ((nodeA.nodeType == NodeType.muscle) && (nodeB.nodeType == NodeType.muscle))
        {
            // Muscle propogation bond
            // Muscle <-> Muscle
            bondType = BondType.thrustPropogate;
            bondBillboard.renderer.material = GameManager.graphics.thrustPropBondMat;

            if (nodeA.thrust > nodeB.thrust)
            {
                nodeB.thrust = nodeA.thrust;
            }
            else
            {
                nodeA.thrust = nodeB.thrust;
            }
        }
        else
        {
            // Not a functional bond.
            bondBillboard.renderer.material = GameManager.graphics.uselessBondMat;
            bondType = BondType.useless;
        }
    }     // End of Update().