prasinos' work memo

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

アイアースのこと

アイアースが何で Ajax になるんかいなという話。
ギリシア神話は当然ギリシア語で、アイアスすなわちAiasと綴ります。というのもギリシア・アルファベットには"j"がないからで、元来ギリシア語で"i"の半母音として発音されていた音に10世紀になってラテン語において"j"の字を作り当てたのですからギリシア語になくても当然。現行のラテン・アルファベットにギリシア人名の"Aias"を置き換えれば"Ajax"ということになるわけです。

#といいつつ、語尾の"s"の"x"への変化はwebmasterには説明つきません。 (Bewaad institute@kasumigaseki - Ajax, again)

こういうことを言っている人がいると黙っていられない。 ギリシャ語の半母音って何だろうという突っこみはほっといて、まずはラテン語形がどうしてできたのかくらいわからないといけない。

で、調べてみたけどかえってわからなくなった。 まず、ラテン語ではこう変化する (田中秀央「羅和辞典」)。

  • 主格 Ajax
  • 属格 Ajacis
  • 与格 Ajaci
  • 対格 Ajacem
  • 奪格 Ajace
ま、要するに語幹は Ajac- なわけ。 ちなみにふたつ出て来る A は両方長いので、 素直に片仮名にすればアーヤークスです。

で、これがどういうギリシャ語から出て来たか。 つっても主格はすでに判っているのだけど、 語幹がどうなっているかわからなきゃ ギリシャ語型が判ったことにならない。

で、普通は第三変化名詞は語幹がそのまま輸入されるので、

  • 主格 *Aiaks → k 脱落して Aias
  • 属格 *Aiakos
つーパターンかなあと思った。

しかし、全然ちがった。そもそも色々音を脱落させるのが好きなギリシャ語だけど -ks は許される (スフィンクスとかξで終るやつ) ので残らないとまずい。

で、辞書がないかなあと思っていたら見付けた。 シカゴ大学図書館の Woodhouseとかで画像が見れるのでフォント腐っている人でも間違いなし。

本家ギリシャ語ではこう変化する。

  • 主格 Aias
  • 属格 Aiantos
  • 与格 Aianti
  • 対格 Aianta
最初の Ai が二重母音で鋭アクセント、次の a が長いので、 「アイアース」である。最初の「アイ」を高く発音するので 日本語としては大変不自然だけどしょうがない。

それはさておき、語幹はなんと Aiant である。ラテン語で -t 幹が認められないわけでもないのに、どうしてこれが Ajax になるわけ?

スポンサーサイト

レポート書きと bibtex

プログラミングのデスマーチは先週まで。ここ数ヵ月のレポートを書いている。 また来週文章書きのデスマーチになるだろうけど。

ワープロは TeX を使うことにした。リモートから編集できないし svn で差分管理とかできないので Word は嫌だった。本当は TeX は嫌いなので groff を使いたかったのだけれど、いくらなんでも時代遅れすぎるのであきらめた。TeX を嫌っていたのもなんだか若気の至りというか学歴コンプレックスみたいなもんだったのかもしれないと思う。

そのおかげでいいこともあった。BibTeX が使える。これも食わず嫌いで長いこと使っていなかったのだけれど、やってみると相当便利だ。まだ Makefile の書き方が安定しないけれど、とりあえず使えるようにはなった。 文章を書き直して消えてしまった引用が巻末に残っているといったみっともない事態を避けるべく気を使う必要がなくなるというのは信じられないくらい気が楽になる。 引用するのはアカデミックなジャーナルじゃなくて、Web とか非伝統的なものばかりなので、何がどう出力されるのか試行錯誤した。で、何が使われるのかリストが必要だったので ここ の説明が大変役に立った。

肝腎の中味。最初は何も参照しないで章立てを考えようとして、うまくいかなくて頭をかかえていた。が、ふと思いだしてうちのセンターのスタイルマニュアルを読み返してみると疑問氷解。

  1. Introduction
    1. Hypotheses
    2. Research Objectives
    3. Format of Document
  2. Background
  3. Study area
  4. Data Sources
  5. Methods
  6. Results and Discussion
  7. Conclusions and Recommendations
  8. References
という作りなのだ。ミソは Introduction と Background を分けてあるところ。レビューは Background に追いやるので Introduction は自分の問題にフォーカスされる。これまで私が親しんで来た流儀では Background → Introduction → ... となるべきところだが、これだと多様な背景の潮流を一本の流れに無理矢理押しこむために四苦八苦する。

良いスタイルというものにはそういう智慧が詰まっているものだ。

世界最小ハリボテWMS

WMS の Capability XML をいじって WMS クライアントの挙動を観察しようとすると、マトモな WMS を使っていたのではまどろっこしい。せっかく XML なんだから、ここは直接 Capability XML を編集したいところだ。なのでそういうサーバを作ってみた。 続きを読む

Unidata IDV のインストール

WMS には多次元拡張というのがある。規格上は一応あるわけだが、一体、誰か使っているのだろうかという疑問がある。WMS クライアントのなかで一番やりそうなのは、Unidata IDV だ。 というわけでダウンロードしてみた。

uDig みたいに Java プログラムでインストーラつきで配られている。で、こいつは偉い。ちゃんと「インストール済の JRE を使いますか? 」と聞いてくる。怖いもの見たさで GCJ を使わせてみる... インストール後起動しない。次は uDig について来た JRE を使わせてみる。画面は出るが adde.ucar.edu から METAR をダウンロードして表示するところでぬるぽ。結局のところ附属の JRE を使わざるを得なかった。Java プラットフォームというものに関する信頼性がイチヂルシク減退せざるをえない体験である。

で、自作 WMS から画像を拾って表示するわけだが、かなりいじらないといけなかった。まず、WMS は gif 対応していないといけない。今どき GIF かよけっという感じであるが。それから、 cgi-bin/script?&service=wms などというふざけた URL を送ってくるので我が WMS が内部でぬるぽ。あのなあ。

それから、IDV は Unidata 様が作って下さっているメニューに載っている WMS はさくっとつなげるが、そうでないとアドレス手打ちしなくてはいけない。iモードメニューみたいなやつだ。それで、手打ちアドレスには service=wms&request=getCapabilities が入っていないといけない。こっちはコピペで済ませたいわけ。もうちょっと考えろよと言いたい。

そういうわけで、時間をサポートした WMS みたいなはりぼてを作って試してみないといけない。

system はしたいが出力はみたくない場合

CGI 内で出来合いコマンドを起動するとき。 セキュリティの寒天から system に配列を与えて他コマンドの起動を防止したいが、そうするとリダイレクトができなくなる。 で、CGI 出力に交ざると大変具合がわるい。 で、fork して $stdout をクローズしてもいいんだけど、プロセスの無駄使いは怖いからやめておきたい。 で、とりあえずこうすれば逃げれることが判明。
null = "/dev/null"
puts 'before'
system '/bin/echo', 'echo', '1'
stdo = $stdout.dup
stde = $stderr.dup
$stdout.close
$stderr.close
$stdout.reopen(null)
$stderr.reopen(null)
r = system '/bin/echo', 'echo', '2'
$stdout.reopen(stdo)
$stderr.reopen(stde)
puts "after r=#{r}"
なお、$stdout を変なオブジェクトにして隠密裡に CGI.escapeHTML したりしていると当然罰が当るので要対処。

書き忘れたことなど。

1. MSIE でコントロール切り替えを試してみた。 画面が崩れて使いモノにならなかった。 IE でコンボボックスの縱を延ばす方法を調べる必要がある。

2. uDig 1.1.M7 は 1.0.6 とくらべて大分マトモ(失礼!)に見える。安定版だからと言わずぜひ 1.1 を使ってみるべきだ。

3. どっかのパンドラみたいにデータサービスを CGI#path_info が普通のディレクトリツリーみたいに見えるようにやろうかと思った。でも、作成処理番号やら格子系をどうやって文字化したらいいか悩んだ。しばらく悩んで、これはあきらめるのがいいと考えなおした。いいかえると単GRIBに与えたIDだけでノベタンにアクセスさせたらよろしかろう。どうせ原状の detail 画面もそうなっているわけだし。

Lambert な GeoTiff の作成法

できた。
gdal_translate -a_srs '+proj=lcc +lat_1=34.9999999999 +lat_2=35.0 +lat_0=35 +lon_0=135 +ellps=WGS84 +datum=WGS84' -a_ullr 0 0 300000 500000 -of GTiff d.nc d.tif
経験上、gdalinfo で最下段右側に経緯度が表示されれば mapserver でも勝利。

困ったこと。

  • lat_1 と lat_2 が同じ値だと処理してくれない。 34.9999999999 というのは逃げ。

latlong NetCDF は楽勝、しかし Lambert NetCDF は敗北

だめだった。 副産物は proj のマニュアル を発見したことくらいだ。 結局のところ
Firstly GDAL doesn't support all versions of netCDF (there are a lot, it is a generic format), so for stability it may be necessary to convert the files into GeoTiff format first.
という不吉な言葉(参照)におとなしくしたがっておけばよいという結論となる。

latlong GeoTIFF の表示に成功

なんとか自作 GeoTIFF を Mapserver が表示できるようになった。 続きを読む

gdal_translate: ラスタファイルの変換

gdal_translate を試してみた。ruby 手打ちで NArray.new.indgen だけの中味の NetCDF を作って、いろいろ属性をつけて gdal_translate(1) を使って GeoTIFF, ESRI ASCII Grid に変換してみた。結果はがっくりである。

gdal_translate は CF コンベンションの投影情報を読まないくさい。頑張っていろいろ書いてみたが TIFF 出力を GeoTIFF 化するには +a_srs オプションが必要みたいである。べつに嫌だってんじゃないけど、馬鹿みたい。

ArcMap もあまり頭よくない(バージョン要確認)。GeoTIFF タグをサポートしているとヘルプに書いてあるのに、どうしてもジオリファレンスが無視されてどんなデータも赤道ギニア行きになってしまう。

ま、結論としてはあまりファイルに情報を含めて楽になろうと無理をしないほうがよろしいようで。Mapserver でいうと、map ファイルにプロジェクション情報を書かざるを得ない。

Gmail で読めないメール

Subject が ISO-2022-JP の Quoted Printable で、本文が Base64 Encoding の UTF-8 というメールがきたら Gmail が本文を解読できなかった。バグだと思うのだが、自信がない。

ruby-netcdf 使ってみる

リファレンスみながらホイホイと書いてみる。 こんなんだったかなあ。 よく覚えていない、ということは、つまり、使ったことがないのだろう。 続きを読む

ruby-netcdf 途中経過

ruby-narray だけじゃなかった。

今日日の ruby-netcdf は贅沢になっていて ruby-narray_miss, libdap, libnc-dap が必要らしい。 それも当然 BuildRequire 指定だ。 そういうわけでビルドしまくり。 幸い SRPM はほとんど手を加えないでビルドできる。

現在は libdap を回避したパチモンで ruby-netcdf のテスト中。

uDig 日本語表示成功! すばらしい!!!

できました。すばらしい。パチパチパチ。 たくぼさんありがとうございます。
uDig が行田市の人口密度を表示しているところ (データ: 平成12年国勢調査)。
メモ
  • バイナリ jar を 1.1.M7 で動作確認。1.0.6 じゃだめ。

RPM 作り: 第二以降のソースアーカイブを自力で開くの法

Maximum RPM まで行かなくても http://vinelinux.org/manuals/making-rpm.html 見れという話。
tar.gzでないソースファイルは、-Tオプションを利用して、 作業ディレクトリに移動した後、
lha x ${RPM_SOURCE_DIR}/hoge.lzh
とかして展開することもできます。

narray

割と簡単にインストールできた。 覚えておくべきこと:
irb(main):008:0> NArray.to_na("\1\0\0\0\xff\0\0\0", NArray::INT)
=> NArray.int(2):
[ 1, 255 ]
リトルエンディアンつーかマシンエンディアンである。

DB スキーマ update

こういう絵は載せるのを忘れると急速に陳腐化するので手離れ前に。 db-060417.dia.txt db-060417.gif

気がつくと足元ボロボロ: NetCDF 以前の問題

GRIB データベースは一段落。
  • 多数のコンボボックスが縦に並ぶと相当スクロールしないとならず、不便なので全部重ねて表示してタブ表示のように見たいところだけを表示するようにした。要 JavaScript というのが難点だが、軽快。わかりにくい & 非 JavaScript 対応の為従来ページを選べるようにすべきだがまだやってない。 また、他ブラウザのテストやさらなる Ajax への進化等もやりたいが多分時間ないだろう。
  • ruby-grib の拡張・デバグ。Thinned Grid を規則格子に拡張する bds_fnrect, bds_firect, bds_nrect を作った。f がついているやつは base, scale を乗じて実数にしたもの、nrect は最近傍代入、irect は線形補間である。整数型で線形補間は意味が無いのでやらない。最初は全部線形補間でいいと思ったが、カテゴリ量などトラブルが理論上ありうるので最近傍代入を用意すべきである。で、初めて実データから 73x73 thinned grid の表を作るテストをして気がついたが格子数が 1/4 になっている。何が悪いかというと C インターフェイスの返す格子数が間違ってオクテット数扱いされていたのである。

それでようやく次が考えられるようになった。 NetCDF を作らねばならん。 mapserver の文書によると Mapserver が NetCDF CF を読んで WCS で GeoTIFF を吐くということができるらしい。 さらに、 gdal_translate というものでコマンドライン変換も可能らしい。 NetCDF さえ出来ればこのへんでなんとかできる。 で、NetCDF だが、ruby-netcdf を入れる前に ruby-narray すらなかった。gfd-dennou.org をあさったら SRPM が消えていた。ぐずん。自分で SPEC 書きます。

プレゼンは乗り切った

とりあえず ldmgribdb のデモはできた。DB 構造も昨日は 不満たらたらだったのだが、今日になったらもうどうでもよくなった。

UML を描いているうちに bull と filpos が一対一対応していることに気がついたので、これは統合した。 それから、rdset を消すうまい方法がないことが発覚したので create table rdfile(id serial, rdset bigint, file bigint, index file(file), unique key uniq(rdset, file)); してこっちからさぐりを入れることにした。

インデックスだけというのもいいものだ。データファイルを持っていないので、 drop database して再構築するだけ。 時間はかかるが、ちょうど、di, dj の計算に問題があって作り直したいところだったのでちょうどよかった。 UI CGI に至っては filpos を参照していなかったので 1行も変更しなくてよかった。

DB のリストラ

早く WMS に行くために、早く Web カタログの UI に進むために、とっとと DB 構造なんか fix したいのだけど、実際には DB 構造の微修正がなかなか終らない。まだ、一発で完璧なスタイルが作れるほど慣れていない。とりあえず、現況。

今日は part から ftime と level を分割した。UI でボタンだか option になっているものは組み合わせキーじゃなくて1つのキーを割り当てたほうがいいからだ。また、param に重複したエントリが多数発生していることに気が付いたので、pcode < 128 のときは ctr = 0 に正規化することにした。これに伴いデータ移行が発生したが、せんだっての Table クラスは非常によく機能して、cron による grib2db の起動間隔内に create table new -> 移行プログラム作成 -> データ移行 -> alter table new rename old; drop table old まで完遂できた。すばらしい。

絵を描いていて気が付いたのは、filpos と bull は一体化してかまわないんじゃないのか? ということである。何のために分けているのかわからない。ただ、この変更は1時間では終らないだろうから、今日やるとドツボるだろう。我慢我慢。 ldmgrib データベースの構造 (Dia XML) ldmgrib データベースの構造 (GIF) PNG では圧縮率が悪くて fc2 の 250k リミットをオーバーしてしまったのでとりあえず GIF. fc2 では GIF のサムネイルが作れないのでとりあえずこのテキストで御容赦。

/etc/cron.hourly に置くファイルには x ビットを立てましょう

3日も気が付かなかった。すごいバカ。

ruby-grib の predefined grid のバグフィックス

テストしていないプログラムは必ずバグる。なんかそんな感じのバグりかただった。
  • nxlist の元データの配列へのポインタが 1 ずれており、 結果として 0 が入ったり 37 が 37 * 256 になったりしていた。
  • di, dj などで 65534 が nil になっていなかった。

ソフトウェア探しの苦労

rubyco(るびこ)の日記 - ■RubyスクリプトをLaTeXで整形(?)

プログラムは作るのも難しいが探すのも難しい。私なんかは世界が狭いのでまあしょうがないのかなあと思っていたが、 rubyco 先生も同じようにお迷いのようで。偉い人が同じように苦労しているからといって何も救いにはならんのだけれど、やっぱり安心する。

あ、ついでにいっておくと、あんなに試行錯誤過程を細かく書くのは偉い。

さて、難癖つけたいわけではないのだけど、キーワードを太字で印刷したいという希望をみると「どうしてだろう」と思ってしまう。だって、読みにくいじゃない、としか言いようが無いのだけれど。それに、変数とメソッドを区別するというのも無理じゃないでしょうか。まあその、やりたいというのを止めるほどのもんでもないので陰でこそっと言ってみるテスト。

しかしまあ私の感性だってカケラもユニバーサルじゃないわけで。昔さるところでドキュメントを UNIX manpage スタイルで作ったら「読みにくい」と非難轟々。そのとき一番驚いたのが太字と地の文の区別がつかないという声でした。私は manpage をいつも見ているから太字かそうでないかについて常人以上に着目するようになってしまっているのか、と反省しました。

Table クラスと RDB スタイル

Table クラスは大成功である。しかし、新しい悩みが産まれた。 いまのところ、テーブルには次の2種類があるとしている。 本当にこれだけでいいか。 たとえば、id は主キーだけれど auto_increment しない場合があるか。あるよなあ。あれっ俺何かバグってる?

パターン1

シリアルの id と属性のキーたちがいる。属性全部をひっくるめたユニーク制約がかかっている。この表に対して行なう操作は次の通り:
  • getid!(属性, ...): 指定した属性組が存在すればその行の id , 存在しなければ新規に登録して作った行の id を返す
  • register(属性, ...): 指定した属性組を新規に登録して作った行の id を返す

パターン2

シリアルの id と偉い属性たちと偉くない属性たちがいる。偉い属性にだけユニーク制約がかかっている。この表に対して行なう操作は次の通り:
  • getid(偉い属性, ...): 指定した属性組が存在すればその行の id を返す
  • select_fringe(id): 指定した id が存在すればその列の偉くない属性を返す
  • register(偉い属性, ..., 偉くない属性, ...): 指定した属性組を新規に登録して作った行の id を返す

SQL の REPLACE 文

という便利なものがあるのですね。知りませんでした。勉強しましょう。

Table クラスと NULL 無用論

表が増えて来て Mysql クラスを生のまま触るのはもう嫌になったので Table クラスを作っている。要は、GDBM くらい気軽に使いたいけれど、AUTO_INCREMENT やら INDEX によるチューンやら UNIQUE キーが欲しいので RDB にせざるを得ないねえということである。

そうするというと、SELECT id FROM table WHERE key = ? AND key = ? ... という SQL を自動生成するわけだが、ここで NULL があると非常に具合が悪い。やっぱり NULL 不用論となった。

wgrib 情報

テーブルで苦労するくらいならさっさと wgrib の軍門に降ったほうがよかったのかもしれないが、いまさら情報。
  • ホームページ
  • ソースコード なんと wgrib.c がベロっと置いてある。 全テーブルはガリガリっとその中に埋め込み。
  • ライセンス: ソースコードの中に書いてある。
    wgrib.c is placed into the public domain. While you could legally do anything you want with the code, telling the world that you wrote it would be uncool. Selling it would be really uncool. The code was originally written for NMC/NCAR Reanalysis and handles most GRIB files except for the ECMWF spectral files. (ECMWF's spectral->grid code are copyrighted and in FORTRAN.) The code, as usual, is not waranteed to be fit for any purpose what so ever. However, wgrib is operational NCEP code, so it better work for our files.
政府機関のくせに、ここまで粗雑だとかえって何か牧歌的な別世界を見ているようですがすがしい。

スケーラビリティ

GRIB には0から255までの番号とテキストを対応づける表が頻出する。ではこれ、どうやって実装するのがいいか。

昨日は RDB で実装することを考えていた。しかし速度のために GDBM とか生テキストでもいいのかと思った。キーがひとつしかないので変なインデックスも不要だし、逆引きもしないので RDB のメリットがまったくないからだ。

で、実験。

  • 0 から 255 までの Fixnum の一部をキーとして値が入れてある Hash を 0x100000 回引く ... 3.4 秒
  • "0" から "255" までの String の一部をキーとして値が入れてある GDBM を 0x100000 回引く ... 8.7 秒
ハッシュの圧勝である。で、数百行のタブ区切り生テキストのロードや GDBM のオープンには 0.01 秒くらいしかかからないので、ロード部分で差別化は図れない。

結局のところ「最後にバカが勝つ」の法則が実証されてしまった。何行くらいまで成り立つのかは興味あるところだが....

[追記] あまりきちんとした例ではないが、他の 12811 行あるテキストで試してみたらロードに 0.7 から 0.8 秒くらいかかっている模様 (キーの作成に時間がかかれば当然もっと伸びる)。一方同規模の GDBM をロードすると 0.03 秒くらいで済むので、今度はリードオンリーな表は GDBM 優位である。

したがって、おお雑把に言って 500 から 1000 行あたりが境目になるのではないか。これ以上長い表が /etc/ に置いてあったとしても編集したくないし。

言い換えると、2バイトのコード表は GDBM にする価値がある。

vim の q コマンド

昔の vi から伝わる @ コマンドをより便利に使うための機構である。なかなか便利だ。 qa で a レジスタへの記録が始まって、q で終る。次に @a でそのコマンドが再現される。 昔だったらコマンドを考えながら1行に書いてみて、"ayy でヤンクしなければならず、最後の改行が災いするかと心配したりしたもんだけど、q で記録する方式ならば安心だ。

しかし、ワンストロークで @a をくり返すことはできんもんか。 v とかに割り当てればいいんだろうけど....

[即日追記] @@ でくり返される。これなら満足といいたいところだが、アメリカのキーボードでは Shift を押さなければいけない。そのくらい我慢しろって?

echo しない readline

パスワードを端末からとる時の常套句
$stderr.print "prompt"
system "stty -echo"
pwd = $stdin.gets.chomp
system "stty echo"
$stderr.print "\r", pwd.tr('!-~', '*'), "\n"
Matz の御墨付のようだ けれど、もうちょっとカッコいい方法はないもんだろうか。

FC2Ad

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。