UTGB カスタムトラックを作る

西山智明

要約

新しいカスタムトラックを作るには

とする。

背景

UTGBはgoogle wet toolkit (gwt)を用いたweb browserである。ルーラーを用いて範囲を選ぶことができるが、範囲の拡大はあまり容易ではない。染色体と、座標を別のテキストボックスに書き込まなくてはいけないなど、細かい動作で少し不便である。しかし、カスタムトラックを作ることで、 範囲を拡大したり、染色体と座標をscaffold_12:45-6789のような形式で一度にコピー&ペーストしてその領域を閲覧することができるようにすることができる。

情報源

基本的にUTGB Toolkitのホームページ以下を参照します。

http://utgenome.org/
ここがトップページ
http://utgenome.org/development.html
Development Note。重要
http://utgenome.org/quickstart.html
UTGB Quick Start。ここに従ってインストールする
http://utgenome.org/toolkit/
User's Manualとしてリンクされているところ
http://utgenome.org/toolkit/track.html
上記User's Manualの下の方からリンクされている。若干古くなっているようだが重要な情報

準備

mercurial, git とMaven

Development Noteにしたがって開発版をインストールするにはmercurial (hg)とMavenが必要。最近はhgでなくgitでも良いらしい。

mercurial

mercurialはpythonでかかれた、分散型ソースコードバージョン管理システムである。

OS Xでは http://mercurial.selenic.com/downloads/ からダウンロードしてインストールする。

CentOS ではyum install hgでインストールできる。

Maven

Apache Maven http://maven.apache.org/ http://maven.apache.org/download.cgi からapache-maven-3.1.0-bin.tar.gzをダウンロードし、.bashrcに

export M2_HOME=$HOME/apache-maven-3.1.0
export M2=$M2:bin
export PATH=$M2:$PATH
を加えて
source .bashrc
mvn --version
でインストールできたことを確認する。

UTGB Toolkit

Development Noteに従い、
$ hg clone https://code.google.com/p/utgb utgb
$ cd utgb

$ make clean install

ここは、ダウンロードされるものが多いのでやや時間がかかる。スリープして途中で止まっているようなら、Ctrl-Cで止めてから 再度、make clean installとする。

再び.bashrcを編集し$HOME/.utgb/binをパスに追加

export PATH=$M2:$PATH

だったのを、

export PATH=$M2:$HOME/local/bin:$PATH

に変更する。区切り(:)はコロンであってセミコロンではない。(http://utgenome.org/development.htmlはおそらくTypo; http://utgenome.org/quickstart.htmlは正しい)。 さらに、

export UTGB_HOME=$HOME/local/utgb/current

を加える。これで、.bashrcをsourceしてから、

$ utgb
UTGB Shell: version 1.5.9-SNAPSHOT
type --help for a list of the available sub commands.

とでることを確認する。

ゲノムブラウザを作ってみる

まずはQuick Startに従う

$ utgb create demo
$ cd demo
$ utgb gwt
$ utgb compile
$ utgb server

この段階で、アクセス可能になる。 ブラウザで、localhost:8989にアクセスしてエラーが表示され、
err
localhost:8989/demoにアクセスすると Welcome to demoのメッセージとBrowse のボタンが表示される。
Initial demo browser
ここでBrowseのボタンを押せば無事ブラウザー画面に到達する。
Entry arrow to show the bottun to press
The demo browser with tracks

Sample Trackをつくってみる

http://utgenome.org/toolkit/track.html に従ってカスタムのオリジナルTrackを作ってみます。

Sample Code の全体をコピーして、demo/src/main/java/demo/gwt/client/SampleTrack.javaというファイルに書き込みます。

src/main/java/demo/gwt/client/Browser.javaを(UTGBEntry.javaではなくBrowser.java)編集し、

import org.utgenome.gwt.utgb.client.track.TrackFactoryHolder;
を上部に
        TrackFactoryHolder.addTrackFactory
           ("demo.gwt.client.SampleTrack", demo.gwt.client.SampleTrack.factory());
をmainの次の行に挿入します。

View XML の代わりにconfig/view/default-view.silkを編集し

-track
  -name: Sample
  -pack: true
  -class: demo.gwt.client.SampleTrack
を加えます。
utgb compile
を実行し、
utgb server

で起動してからふたたび、localhost:8989/demo をアクセスします。

sample track is working!

オリジナルのTrackを作ってみる

UTGB version 1.2.Xの頃にヒメツリガネゴケ用に作ったトラックを、最新版で動くように対応させたものが以下である。 gwtのバージョンが上がって廃止されたものの対応などが必要であった。

下記の内容のファイルを、src/main/java/demo/gwt/client ディレクトリにSelectTrack.javaという名前で作成する。

package demo.gwt.client;

import org.utgenome.gwt.utgb.client.track.Track;
import org.utgenome.gwt.utgb.client.track.TrackBase;
import org.utgenome.gwt.utgb.client.track.UTGBProperty;
import org.utgenome.gwt.widget.client.Style;

import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyUpEvent;
import com.google.gwt.event.dom.client.KeyUpHandler;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Hyperlink;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;

public class SelectTrack extends TrackBase
{
    /**
     * Creates a factory of this track
     * 
     * @return
     */
    public static TrackFactory factory()
    {
        return new TrackFactory() {
            @Override
            public Track newInstance()
            {
                return new SelectTrack();
            }
        };
    }

    private HorizontalPanel panel = new HorizontalPanel();
    private TextBox tb = new TextBox();
    private Button zoomhalf = new Button("x1/2");
    private Button getseq = new Button("getSeq");
    private Button add1k = new Button("+1k");
    private Button add2k = new Button("+2k");
    
    public SelectTrack()
    {
        super("Sample Track");
        // set design

		panel.add(tb);
	        tb.addKeyUpHandler(new KeyUpHandler() {
	           public void onKeyUp(KeyUpEvent event) {
	              int keyCode = event.getNativeKeyCode();
	              if (keyCode == KeyCodes.KEY_TAB || keyCode == KeyCodes.KEY_ENTER){
	        	  String locationstr = ((TextBox)event.getSource()).getText();
	        	  if(locationstr.matches("\\w+:-?\\d+--?\\d+")){
	        		  String[] ary  = locationstr.split(":");
	        		  String targetname = ary[0];
	        		  String location = ary[1];
	        		  if (location.indexOf('-') == 0){
	        			  location=location.substring(1);
	        		  }
	        		  String[] locary = location.split("-",2);
	        		  int startpos= Integer.parseInt(locary[0]);
	        		  int endpos = Integer.parseInt(locary[1]);
	        		  if (startpos < 0){
	        			  int temp = endpos;
	        			  endpos = startpos;
	        			  startpos = temp;
	        		  }
	        		  if (endpos < 0){endpos = -startpos;};
	        		  if (startpos < 0){startpos = -startpos;};

	        		  getTrackGroup().getPropertyWriter().setProperty(UTGBProperty.TARGET, targetname);
	        		  getTrackGroup().getPropertyWriter().setTrackWindow(startpos, endpos);
	        	  }else if(locationstr.matches("^\\d+--?\\d+")){
	        		  String[] locary = locationstr.split("-",2);
	        		  int startpos= Integer.parseInt(locary[0]);
	        		  int endpos = Integer.parseInt(locary[1]);
	        		  if (endpos < 0){endpos = -startpos;};
	        		  if (startpos < 0){startpos = -startpos;};
	        		  getTrackGroup().getPropertyWriter().setTrackWindow(startpos, endpos);
	        	  }
	        	  
	          }
	        }
	      });


        panel.add(zoomhalf);

        zoomhalf.addClickHandler(new ClickHandler(){
            public void onClick(ClickEvent event)
            {
            	int startPosOnGenome = getTrackGroup().getTrackWindow().getStartOnGenome();
            	int endPosOnGenome = getTrackGroup().getTrackWindow().getEndOnGenome();
            	int width = endPosOnGenome-startPosOnGenome+1;
            	if(startPosOnGenome < endPosOnGenome){
            		startPosOnGenome -= width/2;
            		if(startPosOnGenome < 1)startPosOnGenome = 1;
            		endPosOnGenome += width/2;
            	}else{
            		startPosOnGenome += width/2;
            		endPosOnGenome -= width/2;
            		if(startPosOnGenome < 1)endPosOnGenome = 1;
            	}
            	getTrackGroup().getPropertyWriter().setTrackWindow(startPosOnGenome, endPosOnGenome);
            }
        });


        panel.add(add1k);
        add1k.addClickHandler(new ClickHandler(){
            public void onClick(ClickEvent event)
            {
            	int startPosOnGenome = getTrackGroup().getTrackWindow().getStartOnGenome();
            	int endPosOnGenome = getTrackGroup().getTrackWindow().getEndOnGenome();
            	if(startPosOnGenome < endPosOnGenome){
            		endPosOnGenome += 1000;
            	}else{
            		startPosOnGenome += 1000;
            		endPosOnGenome -= 1000;
            		if(startPosOnGenome < 1)endPosOnGenome = 1;
            	}
            	getTrackGroup().getPropertyWriter().setTrackWindow(startPosOnGenome, endPosOnGenome);
            }
        });
        panel.add(add2k);
        add2k.addClickHandler(new ClickHandler(){
            public void onClick(ClickEvent event)
            {
            	int startPosOnGenome = getTrackGroup().getTrackWindow().getStartOnGenome();
            	int endPosOnGenome = getTrackGroup().getTrackWindow().getEndOnGenome();
            	if(startPosOnGenome < endPosOnGenome){
            		startPosOnGenome -= 2000;
            		if(startPosOnGenome < 1)startPosOnGenome = 1;
            		endPosOnGenome += 2000;
            	}else{
            		startPosOnGenome += 2000;
            		endPosOnGenome -= 2000;
            		if(startPosOnGenome < 1)endPosOnGenome = 1;
            	}
            	getTrackGroup().getPropertyWriter().setTrackWindow(startPosOnGenome, endPosOnGenome);
            }
        });
        panel.add(getseq);
        getseq.addClickHandler(new ClickHandler(){
            public void onClick(ClickEvent event)
            {
            	long startPosOnGenome = getTrackGroup().getTrackWindow().getStartOnGenome();
            	long endPosOnGenome = getTrackGroup().getTrackWindow().getEndOnGenome();
            	String target = getTrackGroup().getPropertyReader().getProperty(UTGBProperty.TARGET);
            	String url = "/cgi-bin/getSeq?targetregion=".concat(target).concat(":").concat(String.valueOf(startPosOnGenome)).concat("-").concat(String.valueOf(endPosOnGenome));
            	Window.open(url,"_blank","");
            }
        });
    }

    public Widget getWidget()
    {
        return panel;
    }

}

Browser.javaを編集し、

        TrackFactoryHolder.addTrackFactory
           ("demo.gwt.client.SampleTrack", demo.gwt.client.SampleTrack.factory());

を加えます。さらに、config/view/default-view.silkに

-track
  -name: demo selecter
  -class: demo.gwt.client.SelectTrack

を加え、utgb compile; utgb serverを実行してアクセスします。

UTBG with new custom track

左端の文字入力枠にchr1:100-10000形式の文字列を入力すると、その範囲を表示します。ここで+2kのボタンを押すとブラウズする範囲が左右に2kb大きくなり、1/2 を押すと、中心からの距離が2倍になるまで範囲が広がります。ただし、末端を超えて広がらないようにしてあります。getSeqボタンは配列を取得するためのURLを生成して別windowで開きます(配列を返すためのAPIは別に用意するものとする)。

注意点

$Id: UTGB-custom-track.html 75 2013-10-19 07:52:14Z tomoaki $