💎

タンパク質の3次元構造をNextjsで表示する (Molstarを使用)

2023/09/16に公開

本記事では、タンパク質の3次元構造を簡単に確認するためにWebベースの表示ツールであるMol* (molstar) について紹介します。

Mol* (molstar)とは

Mol* (molstar)とは、分子データの視覚化と分析のためのWebベースのOSSツールです。

生物学分野においては、タンパク質の立体構造の表示に使用されています。代表的な使用例としては、AlphafoldDBでの表示の使用などがあります。

しかしドキュメントがあまり発達していないため、使用法の理解に苦しみました。
そのため、本記事では、最低限使用できるようになったところまで共有したいと思います。
本記事では、Nextjsを使用しますが、jsとcssをほぼ直接使用するため、他のjsプロジェクトでも、同様に使用できるようになると思います。

最終目標画面
sample

Nextjsへの導入

結論から言うと、npm packageは使いこなせませんでした。(2023/9/1時点)
そのため、私は、Githubに公開されているコードから自前でビルドし、使用しました。

https://github.com/molstar/molstar

導入

ツールのビルド

$ git clone https://github.com/molstar/molstar.git
$ npm install
$ npm run build

ツールの配置

ここでビルドが完了します。 /build  に移動し、 viewerフォルダを探します。
viewerフォルダの中には、molstar.jsmolstar.cssが存在することを確認します。

このviewer フォルダを NextjsプロジェクトのPublic配下にコピーします。 本ツールは、クライアントサイドで使用することを前提としているため、クライアントサイドから呼び出せるように配置しましょう。(私は、molstarという名前に変更してコピーしました。)

$ cp -r /build/viwer  ../path-to-your-nextjs-project/public/molstar

index.jsの修正

index.jsにあるgneの変数の一部を、修正します。この修正により、デフォルトでhttp://localhost:9000/v2 にfetchを送り、エラーになることを防げます。
(本来、cneの設定で変更し、自前のサーバーを使用できるようになるはずですが、その設定がわからなかったため、直接変更しました。)

var cne =
            "undefined" != typeof window &&
            "localhost" ===
              (null ===
                (ene =
                  null === window || void 0 === window
                    ? void 0
                    : window.location) || void 0 === ene
                ? void 0
                : ene.hostname),
          gne = {
            DefaultServer: new cJ(
              "volseg-volume-server",
              F9
              //   cne ? "http://localhost:9000/v2" : F9
            ),
          },

最後に、_app.tsxなどにCSSを登録しましょう。

import "../../public/molstar/molstar.css";

以上の設定で準備は完了です。

表示

molstarでは、pbdファイルを表示することができます。
私の確認済みの範囲では、LocalのPBDファイル、EmdbのPBDファイル、AlphaFoldDbのPBDファイルが使用可能でした。EmdbとAlphaFoldDbの場合は、IDを指定することで、表示が可能です。本記事では、AlphaFoldDbを使用する方法を紹介します。

src/componentMolStarViewer.tsxを作成します。
(getPublicPathについては、各自publicへのpathの書き方があると思います。特に変更していなければ、生のPathで問題ないと思います。)

import React, { useEffect } from "react";
import AFLegend from "./AFLegend";
import { getPublicPath } from "../utils/get-public-path";

interface MolStarViewerProps {
  alphafoldId: string;
}
function MolStarViewer({ alphafoldId = "A0A059PIQ0" }: MolStarViewerProps) {
  useEffect(() => {
    async function loadStructure() {
      if (typeof window !== "undefined") {
        const script = document.createElement("script");
        script.src = getPublicPath("/molstar/molstar.js");
        document.body.appendChild(script);
        script.onload = async () => {
          const molstar = (window as any).molstar;
          if (molstar && molstar.Viewer) {
            molstar.Viewer.create(alphafoldId, {
              layoutIsExpanded: false,
              layoutShowControls: true,
              layoutShowRemoteState: true,
              layoutShowSequence: true,
              layoutShowLog: true,
              layoutShowLeftPanel: false,

              viewportShowExpand: false,
              viewportShowSelectionMode: true,
              viewportShowAnimation: true,

              pdbProvider: "rcsb",
              emdbProvider: "rcsb",
            }).then((viewer: any) => {
              viewer.loadAlphaFoldDb(alphafoldId); // ここでloadを変更可能
            });
          } else {
            console.error("Molstar object or Viewer is not defined");
          }
        };
      }
    }

    loadStructure();
  }, [alphafoldId]);

  return (
    <div className="flex mb-10">
      <div
        className="w-1/5 p-4 border-r"
        style={{
          height: "500px",
        }}
      >
        <AFLegend />
      </div>
      <div className="flex w-4/5 p-4">
        <div
          id={alphafoldId}
          style={{
            position: "absolute",
            height: "500px",
            width: "800px",
          }}
        />
      </div>
    </div>
  );
}

export default MolStarViewer;

次に、Alphafold用のLegendを作成します。
src/componentAFLegend.tsxを作成します。

import React from "react";

function Legend() {
  return (
    <div className="columns small-12 medium-3 entryViewerLegend bg-gray-100 text-black p-4">
      <div className="row column relative">
        <h3 className="entrySectionHeading text-2xl font-semibold">
          3D viewer
        </h3>
      </div>
      <div className="row column legendHeading text-xl font-medium mt-2">
        Model Confidence:
      </div>
      <div className="row column legendRow flex items-center mt-1">
        <span className="legendColor bg-blue-700 w-5 h-5 mr-2"></span>
        <span className="legendlabel text-lg">Very high (pLDDT &gt; 90)</span>
      </div>
      <div className="row column legendRow flex items-center mt-1">
        <span className="legendColor bg-blue-300 w-5 h-5 mr-2"></span>
        <span className="legendlabel text-lg">
          Confident (90 &gt; pLDDT &gt; 70)
        </span>
      </div>
      <div className="row column legendRow flex items-center mt-1">
        <span className="legendColor bg-yellow-400 w-5 h-5 mr-2"></span>
        <span className="legendlabel text-lg">Low (70 &gt; pLDDT &gt; 50)</span>
      </div>
      <div className="row column legendRow flex items-center mt-1">
        <span className="legendColor bg-orange-400 w-5 h-5 mr-2"></span>
        <span className="legendlabel text-lg">Very low (pLDDT &lt; 50)</span>
      </div>
      <div className="row column legendDesc text-base mt-2">
        AlphaFold produces a per-residue confidence score (pLDDT) between 0 and
        100. Some regions with low pLDDT may be unstructured in isolation.
      </div>
    </div>
  );
}

export default Legend;

以上で、表示したいページでロードすることで表示ができるようになります。

import MolStarViewer from "../components/MolStarViewer";
...
 <MolStarViewer alphafoldId={proteinId} />

Tips

使用法は、いろいろあるようですが、ドキュメントがあまり発展していないため、直接コードの該当部分など を参照すると良いと思います。

Discussion