Hatena::Groupkdri

KazusaAPI開発日誌 このページをアンテナに追加 RSSフィード

2008-04-20

gbrowse の cgi-bin/das は文字列のエスケープ処理をしていないので、Invalid は XML を書き出してしまうことがある。

|  gbrowse の cgi-bin/das は文字列のエスケープ処理をしていないので、Invalid は XML を書き出してしまうことがある。 - KazusaAPI開発日誌 を含むブックマーク はてなブックマーク -  gbrowse の cgi-bin/das は文字列のエスケープ処理をしていないので、Invalid は XML を書き出してしまうことがある。 - KazusaAPI開発日誌  gbrowse の cgi-bin/das は文字列のエスケープ処理をしていないので、Invalid は XML を書き出してしまうことがある。 - KazusaAPI開発日誌 のブックマークコメント

DASGFF XML の NOTE エレメントのテキストに & があるときに、そのまま & にしていた。これは Invalid な XML になってしまい、XML パーザが許容しない。Ruby だと #<RuntimeError: Illegal character '&' in raw string "two-component hybrid sensor & regulator"> (REXML::ParseException) のようなことになる。

<NOTE tag="Note">two-component hybrid sensor & regulator</NOTE>

これは次のようにエスケープされるべきである。

<NOTE tag="Note">two-component hybrid sensor &amp; regulator</NOTE>

ruby で REXML を使用して XML 文章をつくると、次のようにエスケープされる。

>> require 'rexml/document'
=> true
>> doc = REXML::Document.new
=> <UNDEFINED/>
>> doc.add_element('NOTE').add_text("A & B").to_s
<NOTE>A &amp; B</NOTE>

コードの改変で対応してみた。

gbrowse-1.69 の cgi-bin/das の 386 行と 392 行を改変して対応した。

385   if (@notes) {
386     $group_info = join "\n",map {qq(<NOTE>) . escapeHTML($_) . qq(</NOTE>)} @notes;
387   }
388 
389   if ($attributes) {
390     for my $tag (keys %$attributes) {
391       my @values = ref($attributes->{$tag}) ? @{$attributes->{$tag}} : $attributes->{$tag};
392       $group_info .= qq(\n\t<NOTE tag="$tag">) . escapeHTML($_) . qq(</NOTE>) foreach @values;
393     }
394   }

基本的には、qq(<NOTE>$_</NOTE>) を qq(<NOTE) . escapeHTML($_) . qq(</NOTE>) のように escapeHTML を使うようにした。

まとめ

  1. gbrowse 1.69 の das の出力に不正なXMLがあることがある。
  2. 原因はXML文章作成時にエスケープ処理をしていないこと。
  3. das のソースコードを改変して対応した。

2008-04-13DAS Registray

DAS REGISTRATION サーバのウェブサービスAPIを Ruby と BioRuby からつかってみる

|  DAS REGISTRATION サーバのウェブサービスAPIを Ruby と BioRuby からつかってみる - KazusaAPI開発日誌 を含むブックマーク はてなブックマーク -  DAS REGISTRATION サーバのウェブサービスAPIを Ruby と BioRuby からつかってみる - KazusaAPI開発日誌  DAS REGISTRATION サーバのウェブサービスAPIを Ruby と BioRuby からつかってみる - KazusaAPI開発日誌 のブックマークコメント

目次

DAS Registryは DAS データソース(サーバ)の登録と発見のための登録サービスです。ウェブブラウザで人がサービスの発見をするだけではなくて、クライアントアプリケーションからウェブサービス API を通してサービスの発見をすることができます。

no titleを参考にして、提供されている機能を眺めながら、Ruby から利用してみます。

screenshot


DAS Registryは、登録データへのアクセスのために二種類のウェブサービスを用意しています:

  1. http - XML ウェブサービス(REST
  2. SOAP ウェブサービス

http - XML ウェブサービス(DAS スタイル)

REST 的に URL を GET すると、XML でリソースが返ってくるウェブサービスです。登録データを一覧したり、条件でとりだすための4つのメソッドが用意されている:

  1. sources -- 登録データソースの一覧
  2. organism -- 登録生物種の一覧
  3. coordinatesystem -- 登録データソースの座標系の一覧
  4. lastModified -- 最終更新

これらのメソッドをつかうと、no title のページと同等のページが作成できる。


sources

登録データソースの取得のためのメソッド。引数で問い合わせの条件付けができる。返り値はDTD無しのXMLで返ってくる。

$ curl http://www.dasregistry.org/das1/sources/ 
<SOURCES> 
  <SOURCE uri="DS_109" title="uniprot aristotle" doc_href="http://www.ebi.ac.uk/uniprot-das/" description="This datasource (aristotle) is a legacy  datasource that comprises the new  'uniprot', 'ipi' and 'uniparc'  datasources that are available from the  http://www.ebi.ac.uk/das-srv/uniprot/das  server.  Despite being a legacy dsn,  there are no plans to remove this DAS  datasource from service."> 
    <MAINTAINER email="pjones_AT_ebi.ac.uk" /> 
    <VERSION uri="DS_109" created="2005-03-21T16:26:03+0000"> 
      <COORDINATES uri="http://www.dasregistry.org/dasregistry/coordsys/CS_DS93" source="Protein Sequence" authority="UniParc" test_range="UPI00000017EA">UniParc,Protein Sequence</COORDINATES> 
      <COORDINATES uri="http://www.dasregistry.org/dasregistry/coordsys/CS_DS35" source="Protein Sequence" authority="IPI" test_range="IPI00000021">IPI,Protein Sequence</COORDINATES> 
      <COORDINATES uri="http://www.dasregistry.org/dasregistry/coordsys/CS_DS6" source="Protein Sequence" authority="UniProt" test_range="P00280">UniProt,Protein Sequence</COORDINATES> 
      <CAPABILITY type="das1:sequence" query_uri="http://www.ebi.ac.uk/das-srv/uniprot/das/aristotle/sequence" /> 
      <CAPABILITY type="das1:types" query_uri="http://www.ebi.ac.uk/das-srv/uniprot/das/aristotle/types" /> 
      <CAPABILITY type="das1:features" query_uri="http://www.ebi.ac.uk/das-srv/uniprot/das/aristotle/features" /> 
      <CAPABILITY type="das1:entry_points" query_uri="http://www.ebi.ac.uk/das-srv/uniprot/das/aristotle/entry_points" /> 
      <CAPABILITY type="das1:stylesheet" query_uri="http://www.ebi.ac.uk/das-srv/uniprot/das/aristotle/stylesheet" /> 
      <PROP name="label" value="Predicted" /> 
      <PROP name="label" value="Manually curated" /> 
      <PROP name="label" value="ENSEMBL" /> 
      <PROP name="leaseTime" value="2008-04-13T08:00:01+0000" /> 
      <PROP name="projectHome" value="http://www.biosapiens.info" /> 
      <PROP name="projectIcon" value="http://www.dasregistry.org/ProjectIcon?id=74" /> 
      <PROP name="projectDesc" value="BioSapiens is a Network of Excellence, funded by the European Union's 6th Framework Programme, and made up of bioinformatics researchers from 25 institutions based in 14 countries throughout Europe.



The objective of the BioSapiens is to provide a large" /> 
      <PROP name="projectName" value="BioSapiens" /> 
    </VERSION> 
  </SOURCE> 
[以下省略]

データソースを指定して取得。ここでは、データソース unique ID DS_109 を指定します。

$ curl http://www.dasregistry.org/das1/sources/DS_109

返り値は、http://www.dasregistry.org/showdetails.jsp?auto_id=DS_109の内容と同じ物が XML で返ります。

これを Ruby で扱ってみます。適当に XPath で値を取り出します。

>> require 'open-uri'
=> true
>> require 'rexml/document'
=> true
>> url = "http://www.dasregistry.org/das1/sources/DS_109"
>> xml = REXML::Document.new(open(url).read)
>> coordinates = xml.get_elements('//COORDINATES')[0].text
=> "UniProt,Protein Sequence"
>> xml.get_elements('//COORDINATES')[0].attributes.key
=> ["uri", "test_range", "authority", "source"]
>> REXML::XPath.match(xml, '//COORDINATES')[0].attributes["uri"]
=> 'http://www.dasregistry.org/dasregistry/coordsys/CS_DS93'
>> REXML::XPath.match(xml, '//COORDINATES')[0].attributes["test_range"]
=> 'UPI00000017EA', 
>> REXML::XPath.match(xml, '//COORDINATES')[0].attributes["authority"]
=> 'UniParc'
>> REXML::XPath.match(xml, '//COORDINATES')[0].attributes["source"]
=> 'Protein Sequence'

sources メソッドは、オプション引数をとることができます。引数の種類は、no title の検索の絞り込みでつかっているものと同等です。

これらのオプション引数に使える文字については、残りのメソッドで知ることができます。


organism

登録データソースの生物種の一覧です。NCBI Taxonomy ID や一般名などが含まれます。

$ curl http://www.dasregistry.org/das1/organism
<?xml version='1.0' encoding='UTF-8' ?>
<ORGANISMS>
  <ORGANISM uri="http://www.ncbi.nlm.nih.gov/Taxonomy/Browser/wwwtax.cgi?id=9606" 
 scientificName="Homo sapiens" 
           name="homo sapiens" 
          taxid="9606" />
[以下省略]

Ruby で扱ってみます。

>> require 'open-uri'
>> require 'rexml/document'
>> url = "http://www.dasregistry.org/das1/organism"
>> xml = REXML::Document.new(open(url).read)
>> REXML::XPath.match(xml, "//ORGANISM").size
=> 41
>> REXML::XPath.match(xml, "//ORGANISM[@taxid='9606']").size
=> 1
>> REXML::XPath.match(xml, "//ORGANISM[@taxid='9606']").first.attributes['name']
=> "homo sapiens"

coordinatesystem

登録データソースの座標系の一覧です。

$ curl http://www.dasregistry.org/das1/coordinatesystem
<?xml version='1.0' encoding='UTF-8' ?>
<DASCOORDINATESYSTEM>
  <COORDINATES uri="http://www.dasregistry.org/dasregistry/coordsys/CS_DS62" 
             taxid="9785" 
            source="Chromosome" 
         authority="BROADE" 
        test_range="" 
           version="1">BROADE_1,Chromosome,Loxodonta africana</COORDINATES>
[以下省略]

この uri 属性値のリンク先(http://www.dasregistry.org/coordsys/CS_DS62 へリダイレクトされている)は、上記の内容を人がブラウザで見るような形で提供している XHTML 書類です。また、この uri はユニークな uri になっています。

Ruby であつかってみる。

>> require 'open-uri'
>> require 'rexml/document'
>> url = "http://www.dasregistry.org/das1/coordinatesystem"
>> xml = REXML::Document.new(open(url).read)
>> coords = xml.get_elements("//COORDINATES")
...
>> coords.size
=> 100
>> coords.find_all {|x| x.attibutes['taxid'] == '9609' }.size
=> 12
>> REXML::XPath.match(xml, "//CORDINATES[@taxid='9606']").size
=> 12

lastModified

登録データの最終更新時間を取得することができます。HTTP ヘッダで取得できます。

$ curl -I http://www.dasregistry.org/das1/lastModified
HTTP/1.1 200 OK
Date: Sun, 13 Apr 2008 11:00:52 GMT
Server: Resin/3.0.24
ETag: "AAAARk+SVM4"
Last-Modified: Fri, 11 Apr 2008 16:20:03 GMT
Content-Encoding: ISO-8859-1
Content-Type: text/xml

HTTP ヘッダだけでなく、XML 文章としても取得できるようです。

$ curl http://www.dasregistry.org/das1/lastModified
<?xml version='1.0' encoding='UTF-8' ?>
<LASTMODIFIED time="2008-04-11T16:20:03+0000" />

Ruby であつかってみる。

>> require 'open-uri'
=> true
>> require 'rexml/document'
=> true
>> url = "http://www.dasregistry.org/das1/lastModified"
>> xml = REXML::Document.new(open(url).read)
>> Time.parse(xml.get_elements("//LASTMODIFIED")[0].attributes['time'])
=> Sat Apr 12 01:20:03 +0900 2008


SOAP ウェブサービス

DAS Registry は SOAP によるウェブサービスも提供している。


WSDL

BioJava と Perl SOAP::Liteによる利用サンプルプログラムがno titleにある。


メソッド一覧

SOPA ウェブサービスを Ruby で利用してみる。

require 'soap/wsdlDriver'

wsdl = 'http://www.dasregistry.org/services/das:das_directory?wsdl'
serv = SOAP::WSDLDriverFactory.new(wsdl).create_driver
serv.generate_explicit_type = true

p serv.methods(false)

つぎのように、メソッド名のArrayが返ってくる。

["getDasSource", "getOrganismsByName", "requestKey", "getAllCoordinateSystems", 
 "registerService", "getCoordSysByType", "getCoordSysTypes", "listServices", 
 "findService", "getAllLabels", "validate", "renewLease", "getAllCapabilities", 
 "keywordSearch", "removeService", "getValidationMessage"]

listServices

登録サービスのリストを返す listServices メソッドを実行してみる。

result = serv.listServices

エラーが返ってきた。

SOAP::EncodingStyle::Handler::EncodingStyleError: unknown type '{http://schemas.xmlsoap.org/soap/encoding/}string'
        from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/soap/encodingstyle/soapHandler.rb:371:in `decode_definedtype'
        from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/soap/encodingstyle/soapHandler.rb:366:in `decode_tag_by_wsdl'
        from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/soap/encodingstyle/soapHandler.rb:156:in `decode_tag'
        from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/soap/parser.rb:179:in `decode_tag'
        from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/soap/parser.rb:130:in `start_element'
        from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/xsd/xmlparser/parser.rb:67:in `start_element'
        from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/xsd/xmlparser/rexmlparser.rb:34:in `tag_start'
        from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/rexml/parsers/streamparser.rb:24:in `parse'
        from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/rexml/document.rb:199:in `parse_stream'
        from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/xsd/xmlparser/rexmlparser.rb:27:in `do_parse'
        from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/soap/parser.rb:92:in `parse'
        from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/soap/processor.rb:39:in `unmarshal'
        from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/soap/rpc/proxy.rb:236:in `unmarshal'
        from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/soap/rpc/proxy.rb:175:in `route'
        from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/soap/wsdlDriver.rb:339:in `rpc_call'
        from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/soap/wsdlDriver.rb:543:in `listServices'

型の問題のようである。


BioRuby で対応するとしたらこうしてみたい

以上をふまえて、Class の設計を考えてみたい。たとえば、つぎのようなコードでつかえるとよい。

require 'bio'
reg = Bio::DAS::Registry.new
sources = reg.sources(:organism => '9606', 
                      :capability => 'features', 
                      :type => 'Chromosome')
sources.each do |source|
  source.uri
  source.doc_href
  source.description
  source.maintainer.email
  source.version.uri
  source.version.created
  source.coordinates[0]
  source.coordinates[0].uri
  source.coordinates[0].source
  source.coordinates[0].authority
  source.coordinates[0].test_range
  source.capability[0].type
  source.capability[0].query_uri
  source.prop[0].name
  source.prop[0].value
  source.prop['label']
  source.features(:segment => 'Chr1:1,1000')
end


まとめ

  1. DAS Registry は二つのウェブサービスを提供している。
  2. クライアントがデータソースの発見に通常使うのは sources メソッドである。
  3. SOAP サービスは Ruby の soap4r では使えなかった。
  4. REST 的なウェブサービスはポータブル。
  5. Bio::DAS::Registry はまだない。

2008-04-04

次世代シーケンサ用アセンブラ Velvet を Solaris でコンパイルする

|  次世代シーケンサ用アセンブラ Velvet を Solaris でコンパイルする - KazusaAPI開発日誌 を含むブックマーク はてなブックマーク -  次世代シーケンサ用アセンブラ Velvet を Solaris でコンパイルする - KazusaAPI開発日誌  次世代シーケンサ用アセンブラ Velvet を Solaris でコンパイルする - KazusaAPI開発日誌 のブックマークコメント

Velvet は、サンガー研究所の Daniel ZerbinoEwan Birney らによって開発されている、Solexa や 454 などの短いリード配列のための de novo ゲノムアセンブラです。Velvet は主に 64bit Linux 向けに開発されているので、配布物(0.5.05)をそのまま Solaris 10 ではコンパイルできませんでした。ゲノムアセンブラは、16GB 以上といった大量のメモリを要求するので、Solaris マシンでうごかせると良い場合が割とあるとおもいます。作者が、Solaris 版の開発も進めているということなので、Solaris 版のテスターとして手をあげてみた。

screenshot

(中略)

というようないきさつで、Velvet 0.5.06 は Solaris 10 マシンでコンパイルできました。ありがとう Daniel さん。ついでに、Mac OS X 10.5 でもコンパイルできました。メモリが足りないので動かしてはいません。