2008/11/09

Google App EngineとChart APIを使って簡単な遺伝子発現データベースを作ってみた

追記: コードを整理してgithubにアップしました。http://github.com/dritoshi/gaexpr2/

徹夜のサンプリングの合間にプログラミングをすると、最後までテンションが下がらないライフハックを発見した。しかし寝ぼけた頭で、研究に使うプログラムは書きたくない。そこで前から hack してみたかった Google App Engine と Google Chart APIで遊んでみることにした。[[Google App Engine|http://code.google.com/appengine/]]はGoogleのサーバと開発環境を使ってウェブアプリを作るフレームワークみたいなもの。[[Google Chart API|http://code.google.com/apis/chart/]]はデータを渡すとグラフを返してくれるウェブサービス。

しょぼいが、Pythonを思い出しつつGAEとGCAを覚えつつサンプリングしつつ書いたのがこれ。

http://gaexpr2.appspot.com/search

データは以前書いた [[Ruby on Rails + Gruffを使って、11分で作る遺伝子発現データベース|http://itoshi.tv/d/?date=20060506]]で使ったDNA microarrayのデータを使っている。

Railsも便利だけど、サーバを自分で確保しないといけない。Google App Engine はサーバも提供してくれるし、Googleのリソースを使えるので規模が大きくなってもスケールするんだろうなぁ。Google Chart API も軸の取り扱いに癖があったり、エラーバーが描けなかったりするけど、依存関係が激しくなりがちなグラフ生成ライブラリをインストールする手間がまったくいらないというのは魅力的。

しかし、これだけ簡単だと気軽にデータベースを自作するウェット研究者が増えるんじゃないかな。

コードは以下の通り。あとでgithub.comにも上げておく。
<<<
import wsgiref.handlers

from google.appengine.ext import webapp
from google.appengine.ext import search
from google.appengine.ext.webapp.util import run_wsgi_app

class MainPage(webapp.RequestHandler):
def get(self):

url = "http://chart.apis.google.com/chart?cht=lxy&chco=1E5692,3E9A3B&chs=200x125&chxt=x,y&chxl=0:|0|2|4|6|8|10|1:|2|4|6|8|10&chds=0,10,2,10,0,10,2,10&chd=t:"
self.response.headers['Content-Type'] = 'text/html'
self.response.out.write('')

# I use the webapp framework to retrieve the keyword
keyword = self.request.get('keyword')

if not keyword:
self.response.out.write("No keyword has been set")
else:
# Search the 'Expression' Entity based on our keyword
query = search.SearchableQuery('Expression')
query.Search(keyword)
for result in query.Run():
# Annotation
self.response.out.write('
')
self.response.out.write('Affy ID: %s\n' % result['affy_id'])
self.response.out.write('Gene Symbol: %s\n' % result['gene_symbol'])
self.response.out.write('Gene Name: %s\n' % result['gene_name'])
self.response.out.write('Entrez Gene: ' % result['entrezid'] + "%s\n" % result['entrezid'])
self.response.out.write('
')

# Graph (Using Google Chart API)
evector = ",".join([`result['evector_day' + suffix]` for suffix in ["0", "2", "4", "10"]])
ppargox = ",".join([`result['ppargox_day' + suffix]` for suffix in ["0", "2", "4", "10"]])
graph = url + "0,2,4,10|" + evector + "|0,2,4,10|" + ppargox
self.response.out.write('' % graph)

self.response.out.write('')
self.response.out.write('')

class IdSearchForm(webapp.RequestHandler):
def get(self):
self.response.headers['Content-Type'] = 'text/html'
self.response.out.write("""


Gene Expression Database




Keyword:
(ex. 100005_at, Traf4)




Itoshi NIKAIDO, Ph. D., dritoshi at gmail dot com

""")


application = webapp.WSGIApplication(
[('/', MainPage),
('/search', IdSearchForm)],
debug=True)

def main():
run_wsgi_app(application)

if __name__ == "__main__":
main()
>>>

app.yaml
<<<
application: gaexpr2
version: 1
runtime: python
api_version: 1

handlers:
- url: /load
script: myloader.py
login: admin

- url: /.*
script: gaexpr2.py
>>>

myloader.py
<<<
from google.appengine.api import users
from google.appengine.ext import bulkload
from google.appengine.api import datastore_types
from google.appengine.ext import search

class ExpressionLoader(bulkload.Loader):
def __init__(self):
# Our 'Expression' entity contains a affyid string and an expression float data
bulkload.Loader.__init__(self, 'Expression',
[('affy_id', str),
('gene_symbol', str),
('entrezid', str),
('gene_name', str),
('evector_day0', float),
('evector_day2', float),
('evector_day4', float),
('evector_day10', float),
('ppargox_day0', float),
('ppargox_day2', float),
('ppargox_day4', float),
('ppargox_day10', float),
])

def HandleEntity(self, entity):
ent = search.SearchableEntity(entity)
return ent

if __name__ == '__main__':
bulkload.main(ExpressionLoader())
>>>

Google のAppサーバにプログラムをアップして、
/usr/local/google_appengine/appcfg.py update gaexpr2/
データをロードする。expressions.table.100.txtがデータ(45000ぐらいあるので最初の100行だけ)で、xxxの部分はGoogleにログインして http://gaexpr2.appspot.com/load を表示すると値が得られるのでそれを入れておくこと。
<<<
/usr/local/google_appengine/tools/bulkload_client.py --cookie='ACSID=xxx' --kind Expression --url http://gaexpr2.appspot.com/load --filename expressions.table.100.txt
>>>