Example #1
0
        /// <summary>
        /// 公有构造函数
        /// </summary>
        /// <param name="type">氨基酸类型</param>
        /// <param name="isStandard">是否是标准残基</param>
        /// <param name="atoms">构成氨基酸得原子</param>
        /// <param name="connection">原子间的连接关系</param>
        internal Aminoacid(AminoacidType type, string chinese, bool isStandard, IList <string> atomNames, IDictionary <KeyValuePair <string, string>, BondType> connection)
        {
            this.Type    = type;
            this.Chinese = chinese;

            List <AtomInAminoacid> atoms = new List <AtomInAminoacid>();

            foreach (string name in atomNames)
            {
                AtomInAminoacid atomInAminoacid = new AtomInAminoacid(name)
                {
                    Aminoacid = this,
                };
                atoms.Add(atomInAminoacid);
            }
            //Atoms = new ReadOnlyCollection<AtomInAminoacid>(atoms);

            atomDic = new Dictionary <string, AtomInAminoacid>();
            foreach (var child in atoms)
            {
                atomDic.Add(child.Name, child);
            }

            Dictionary <KeyValuePair <AtomInAminoacid, AtomInAminoacid>, BondType> connectDic = new Dictionary <KeyValuePair <AtomInAminoacid, AtomInAminoacid>, BondType>();

            foreach (var child in connection)
            {
                // this是38行的索引器的调用,即输入原子名字string(含后缀的),返回对应的原子实例
                connectDic.Add(new KeyValuePair <AtomInAminoacid, AtomInAminoacid>(this[child.Key.Key], this[child.Key.Value]), child.Value);
            }
            Connections = new ReadOnlyDictionary <KeyValuePair <AtomInAminoacid, AtomInAminoacid>, BondType>(connectDic);
        }
Example #2
0
        public static Aminoacid Generate(AminoacidType type)
        {
            Aminoacid aminoacid = null;

            if (!Aminoacids.TryGetValue(type, out aminoacid))
            {
                throw new ArgumentException("Unhandled AminoacidType:" + type.ToString());
            }
            return(Aminoacids[type]);
        }
Example #3
0
    /// <summary>根据残基类型获取原子预制体</summary>
    private GameObject GetAtomPrefeb(AminoacidType aminoacidType)
    {
        GameObject prefeb = null;

        if (!AtomPrefebsDic.TryGetValue(aminoacidType, out prefeb))
        {
            prefeb = Resources.Load <GameObject>(string.Format("{0}/{1}", AtomSpherePrefebPath, aminoacidType.ToString()));
            AtomPrefebsDic.Add(aminoacidType, prefeb);
        }
        return(AtomPrefebsDic[aminoacidType]);
    }
Example #4
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;
        }
Example #5
0
 private Material GetHighlightMaterial(AminoacidType aminoacidType)
 {
     return(GetAtomPrefeb(aminoacidType).GetComponent <AtomDisplayer>().highLight);
 }
Example #6
0
 /// <summary>根据残基类型获取材质</summary>
 private Material GetMaterial(AminoacidType aminoacidType)
 {
     return(GetAtomPrefeb(aminoacidType).GetComponent <AtomDisplayer>().normal);
 }
Example #7
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);
    }
Example #8
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;
    }
Example #9
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);
                    }
                }
            }
        }
    }
Example #10
0
 private Material GetMaterial(AminoacidType aminoacidType)
 {
     return(GetAtomPrefeb(aminoacidType).GetComponent <Renderer>().sharedMaterial);
 }