prasinos' work memo

スポンサーサイト

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

DF から Win32 API の DLL を呼ぶ

これも、自作 DLL とそれほど変わるものではない。

ただし、Win32 API の名前に小文字が入っているので、そこの付けかえを !dec$ ... alias: '名前' でやらなければならない。したがって、次の例がよいインターフェイスになるはずなのだが、何か動作がおかしいので追って報告したい。



module winsock_types
implicit none

type wsadata
integer(2):: version
integer(2):: highversion
character(257):: szDescription
character(129):: szSystemStatus
integer(2):: maxSockets
integer(2):: maxUdpdg
integer(4):: lpVenderinfo
end type

type socket_t
integer(4):: ival
end type

type addrfamily_t
integer(4):: ival
end type

type socktype_t
integer(4):: ival
end type

type sockaddr_in
integer(2):: sin_family
integer(2):: sin_port
integer(1):: sin_addr(4)
integer(1):: sin_zero(8)
end type

end module

module winsock
use winsock_types
implicit none
interface

integer(4) function wsastartup(reqver, wsainfo)
!dec$ attributes dllimport, alias: '_WSAStartup@8' :: WSAStartup
use winsock_types
integer(2), intent(in):: reqver
type(wsadata), intent(out):: wsainfo
end function

integer(4) function wsacleanup()
!dec$ attributes dllimport, alias: '_WSACleanup@0' :: WSACleanup
end function

integer(4) function wsagetlasterror()
!dec$ attributes dllimport, alias: '_WSAGetLastError@0' :: WSAGetLastError
end function

function socket(af, type, protocol) result(result)
!dec$ attributes dllimport, alias: '_socket@12' :: socket
use winsock_types
type(addrfamily_t), intent(in):: af
type(socktype_t), intent(in):: type
integer(4), intent(in):: protocol
type(socket_t):: result
end function

integer(4) function closesocket(s)
!dec$ attributes dllimport, alias: '_closesocket@4' :: closesocket
use winsock_types
type(socket_t), intent(in):: s
end function

end interface

type(addrfamily_t), parameter:: AF_UNIX = addrfamily_t(1)
type(addrfamily_t), parameter:: AF_INET = addrfamily_t(2)
type(addrfamily_t), parameter:: AF_INET6 = addrfamily_t(23)
type(socktype_t), parameter:: SOCK_STREAM = socktype_t(1)
type(socktype_t), parameter:: SOCK_DGRAM = socktype_t(2)
type(socket_t), parameter:: INVALID_SOCKET = socket_t(not(0))

integer(4), parameter:: SOCKET_ERROR = -1

interface

integer(4) function bind(s, name, namelen)
!dec$ attributes dllimport, alias: '_bind@12' :: bind
use winsock_types
type(socket_t), intent(in):: s
type(sockaddr_in), intent(in):: name
integer(4), intent(in):: namelen
end function

integer(4) function accept(s, addr, addrlen)
!dec$ attributes dllimport, alias: '_accept@12' :: accept
use winsock_types
type(socket_t), intent(in):: s
type(sockaddr_in), intent(out):: addr
integer(4), intent(out):: addrlen
end function

end interface
end module

スポンサーサイト

地表面気圧だけの再解析

地表面気圧だけで再解析はできる。精度は、現在の2日予報程度だろうということ。

カフェイン抜きコーヒー

アメリカではカフェイン抜きコーヒー (decaffeinated coffee 略して decaf) が非常に普及している。たとえば、ホテルに行ってコーヒーメーカーが置いてあれば、十中八九、レギュラーコーヒーとデカフの粉がある。しかし、このデカフというやつ、どうやって作るのだろうか。

ググってみると、どうやら以下の3種類の方法であるらしい[1][2]。いずれも、コーヒー豆をカフェインだけ溶けてその他の成分(以下面倒なので香り成分といっておく)が溶けないようなものに浸すのである。

溶剤抽出法

カフェインが溶けるような有機溶剤にコーヒー豆を浸す。
1970年代にはジクロロメタン[1]やトリクロロエチレン[3]等が使われたが、発癌性があることがわかったのでダメになった。
1980年代からはエチルアセテートが主に使われている。エチルアセテートは自然の果物にも含まれる物質だからというので、 "naturally decaffeinated" と称して売られるらしい。これが有害という人もあるし[1]、大丈夫だといっている人もいる[3]。コストが低く欧米ではポピュラーらしいが、日本では少なくとも2000年までは許されていなかった(もっとも、有害だと判ったから禁止というわけでなく、食品添加物として認可を誰も申請していないからということであるらしいが)[4]
超臨界二酸化炭素抽出法

なんかすごそうな名前だが、要は超高圧 (72.8気圧以上、31℃以上) の二酸化炭素は液体みたいな状態になっていて、有機物がよく溶けるのだそうだ。安全性は高いがコストも高いらしい。
水抽出法

水(湯)に溶かす方法である。と書くと一瞬わかったような気になるが、カフェインがなくなるくらい水で抽出したコーヒー豆というのは一言で言えば出がらしであって、それをコーヒー豆として焙煎したところで使い物にはならない[3]。なので、何かの方法でカフェイン以外の成分が残るように工夫している。

Swiss Water Process
焙煎前のコーヒー豆を水の入った容器に入れて水を循環させ、活性炭のフィルタに通す。活性炭によってカフェインが吸着されるが香り成分は吸着されないので、長い間循環している間には水が香り成分で飽和して豆から香り成分が抜け出さないようになり、カフェインだけが抜き出せる仕組みとなる、らしい。
間接溶剤抽出法
カフェインや香り成分が丸ごと滲出してしまった水(高温らしいので湯)に有機溶剤を接触させて、カフェインだけを有機溶剤に移し、残った湯を出がらしの豆に吸収させる方法。つまり、間接的だけれど要は有機溶剤を使っているのだが、そういうと聞こえが悪いので Water Processed と称して売られている。ただし、少なくとも米国では FDA の規制があって残存溶剤量は制限されている[5]


そういうわけで、実際に商品に書かれているかもしれない表記は、溶剤が少なそうな順に

  1. "Swiss Water Process," "Supercritical Carbondioxide"
  2. "Water Process"
  3. "Naturally Decaffeinated"

の順となる。実にわかりにくい。

余談。

  • 遺伝子組み換えでカフェインを含まない豆を作ろうとしている研究が日本で行われている(参照)。
  • 一方で、もともとカフェインを含まない豆が発見された(参照)。
  • 米国人のコーヒー消費量は1962年の半分以下となっている(参照)。


参照


Borland C++ から DF の DLL をリンクする方法

さて、諸般の事情から Borland C++ を使うことにする。

●プログラムの書き方


extern __stdcall PROCNAME(引数リスト);


とやって宣言する。C++ ならば当然


extern "C" { __stdcall PROCNAME(引数リスト); }


となる。

●リンクの仕方

さっきの DF の場合と原則として同様であるが、.LIB のバイナリの形式が異なっており、単純に BCC32 WRITTEN_IN_C.C FORTRAN.LIB とやってもエラーになってしまう。しかしボーランド様は救いの手をさしのべてくださるのであった。


COFF2OMF FORTRAN.LIB OMF_FORTRAN.LIB


とやれば、新しいインポートライブラリを作ることができる。これを使ってリンクすればよい。

DF 系の Fortran で DLL を作る法

■能書き

Windows 系の Fortran コンパイラ (ベンダーは DEC, Compaq, Intel と色々しているが、大体仕様はおなじ) は DLL を作ることができる。DLL のご利益はいろいろ謳われているが、多言語多コンパイラプログラミングが簡単になるということが一番大きいと思う。

数値計算は Fortran でしかできないが、GUI を作るために Fortran コンパイラ付属の GUI のライブラリの使い方を調べるのは億劫だと思う。せっかく学んでも他で応用が利かないし。しかし、Fortran で DLL を作って VC++ や VB の GUI からリンクすれば、割と簡単になるかもしれない。(ならないかもしれない)。

■方法

●作る人

公開したい手続きを外部サブルーチン(多分関数でもいいと思うが知らん)とし、SUBROUTINE 文の直後に

!DEC$ ATTRIBUTES DLLEXPORT:: サブルーチン名



と書く。ついで、コンパイルするとき

C>df /dll ソース.f90



のようにする。すると ソース.dll, ソース.lib, ソース.exp が発生する。拡張子 .dll が .so みたいなもので、.lib が .a みたいなもので、.exp は何の役に立っているのかよくわからない。

●使う人

呼びたいサブルーチンを面倒でも interface 文に書く。その中の SUBROUTINE 文の直後に

!DEC$ ATTRIBUTES DLLIMPORT:: サブルーチン名



と書く。あとは、普通に .lib をリンクするだけ。

■メモ

DLL 内部から入出力文も使える模様。これで怖いものなしだ。

G95 で内部サブルーチンをサブルーチン引数にできない件

この制限って規格か? こんな感じのことがやりたいわけですよ。



program foo
call sidekicker(callback)
contains
subroutine callback
print *, 'ok'
end subroutine
end program

subroutine sidekicker(proc)
external proc
call proc
end subroutine


たとえば、ハッシュの総なめ (Hash#each のようなもの) とか作ろうとすると、このようなコールバックにするか、お客様にあらかじめ配列を確保していただいて、全要素ゲットとかいうことになってしまう。その場合、要素数だけじゃなくて、いろいろの情報をお客様にあらかじめ把握してもらって配列を確保しなければならず、ぜんぜんパッケージ作って簡便化にならんわけです。

ま、別にコールバックは外部サブルーチン限定でもいいんですけどね。貴重な外部名という資源ではあるけれど、たった1個だけ使うだけですから。外部サブルーチンで作ったライブラリとかいったもの(20世紀はそれが当たり前だったわけだし)と比べたらかわいいものです。

やばいサイト

某国立公園内の宿のオンライン予約をしたら、その予約に使ったメールアドレス宛のジャンクメールが急増した。2箇所やったので、犯人が断定できないのであるが、そのサイトからなんらかの方法でメールアドレスが漏洩してジャンクメール送信業者に渡っているのはほぼまちがいない。

嫌な世の中になったものだ。

GEMPAK

さっきのエントリは書くのに3時間もかかってしまった。多数の優秀な人が本気でやって要る人の最先端だから、まとめるのも一苦労なんだけど、やらないとねえ。もうちょっと身近に宣伝しないといけないのだが、人様に読ませる文体に構成するためにはもっと手を加えないと行けない。あーしんどい。遣唐使は大変だったと思う。

で、UCAR Unidata が配っている GEMPAK の話。もとは NCEP で作られており、N-AWIPS と呼ばれるものの一部なんだという。AWIPS との関係は不明。それで、ニュースは

・内部ロジックは FORTRAN 77 で書かれている
・API があって FORTRAN から呼ぶことができる

んだそうな。何かに、すごく似ている。

AMS 年会報告

AMS http://www.ametsoc.org/ の年会に行ってきました。その準備とか色々で、更新がしばらく止まっていました。ごめんなさい。(誰も期待していないと思うけど)

そういうわけで、見聞レポートをしなくてはいけないのだけど、あまりに多岐にわたるので、どうまとめていいものやらわからない。とりあえず速記録からメモにいきかけた感じくらいのもの。

●Unidata IDD の中南米進出

IDD はリアルタイム気象データのフィードを行うシステムで、技術的には Usenet に類似したものである。それで、もともと UCAR Unidata を中心として米国の大学でやっていたのだが、最近は海外にもひろがっている。サイト数は

US 209
ブラジル 12
カナダ 3
あと中米諸国

といった感じ。これはいずれ、研究機関間の国際ネットワークとして成長して行くのだろう。どういうわけだか欧州が乗って来ていないが、これは単純に日本と同様に出遅れているだけなのかどうか、よくわからない。

それで、そのブラジル人の言うには、ブラジル近辺の GTS にうまく乗せられないデータがIDD に乗る理由は、データの配信管理の bureaucracy cost の差なんだという。要は、データの中身を把握していないでも送れる土管的なプロトコルであるから、データの中身を同定するための協調作業が要らなくていいんだというわけだ。聞いていて非常な勢いを感じたし、土管の勝利というのはある程度一般化できる技術原則でもある。

●次世代 McIDAS は IDV

こんな感じの講演。

UW-SSEC では 1970 年代から可視化ソフトMcIDAS-X の開発をしてきました。McIDAS はおかげさまで世界各国の幅広いユーザにご利用いただいておりますが、30年以上の時を経た FORTRAN/C コードは保守が不可能となり、対応を1990年代末に終了させていただきました。SSEC では新時代の要請に応えるために、次世代 McIDAS-V の構想をまとめているところです。現在有力な候補は、Unidata IDV です。

なーんだ IDV かよ。新しい物を見るという楽しみはなかった。

VisAD では単位・エラー・座標系などはオブジェクトである。ADDE は TCP ポート 12 として IANA に登録済みである。OpenADDE は ADDE サーバの実装であり、 LGPLで配布。

●AWIPS の Linux への移行

HP から Linux に移行するんだと。OPeNDAP を使う試みをしているが、動作が遅いので警報オペレーションには使えない。

ソフトウェアのアーキテクチャについて、なにか難しい構造を持っているらしいがよくわからなかった。

●Argo Float 用 XML 標準化

PMEL/JISAO の海洋やさん Nazila Merati という人がキーマンであるらしい。何だか良く判らないが「GIS の将来は XML だ!」に乗せられて XML 化やら OGC WFS によるデータ供給を始めたが、 ArcGIS9 が WFS を読んでくれないので困っているのだと言う。じゃ、結局 WFS は何ソフトから使えるのか?

●NOAA/NWS のポリゴン警報

2004 年から警報を郡単位から任意ポリゴンに変える試験をやっているのだという。

2005年には試験運用がいくつかのNWS予報事務所で行われる。ポリゴンから GIS のシェープファイルをつくるプログラムは perl でかかれ ESRI "gen" 形式を書き出す。

さて、はたしてどのような形の領域で警報が出たかというと、トルネード警報やフラッシュフラッド警報は細長くできるから意味がある。強雷雨警報なんかだと、システムはポリゴン対応なのに郡境界に沿って警報を出すマインドセットが予報官に残っている。

http://www.srh.noaa.gov/hq/regsci/gis/ にファイルがあるというのだけど、アクセスしてみると 404 だった。

●データカタログサーバ DIMES, MIDAS

あの GrADS のジョージメイソン大学でデータカタログサーバシステムを作っているんだと言う。OPeNDAP 等でサービスされるデータを探索するために使うという意味で、 THREDDS と似たポジションであるわけだけど、 THREDDS が単なるリストを提供するのに対して MIDAS は検索ができるんだという。

●GIS ベースのデータ閲覧サーバ乱立

NCDC がやっている。気象警報関係がやっている。海上気象もやっている。 いずれにしても、中で GIS が動いている。

●GrADS 最新状況

GrADS 1.9r4 からは、メタデータと称するname-value pair (のように見えるが、型指定もある)をコントロールファイルで定義できるようになり、それが SDF/OpenDAP から取られたメタデータと等価に扱えるようになるのだという。GDS は GrADS で読めるあらゆるデータ(地点データ含む)をサーブできるのだという。

●LAS = Live Access Server と RELAX

内部で ferret/GrADS を動かしてデータを閲覧させるサーバ。PMEL でやっている。THREDDS カタログや OPeNDAP データを読む。それで、コンポーネント間の通信で XML を使っていて、スキーマ記述言語が欲しくて RELAX NG を使っているらしい。

●GeoTIFF データサーバを作ってみた話

Caron グループの仕事で、ASIS と GIS のデータモデルの比較の一環。変換システム作ってみて困ったこと;次元数差、ジオリファレンス情報欠如気象データ、グリニジ分割データをグリニジ中心に回すこと、経度領域ミッシングデータが扱えない、など。Unidata's Common Data Model 計画の一部。変換システムは NetCDF Java 実装の一部として提供予定だという(質疑回答なので聞き違えかも)。GeoTIFF タグは name-value pairs で value には整数・実数・その配列が使える。でも名前は使えないらしく WGS84 楕円体に 4326 なんて番号を割り振っている。つまりこれは表の管理という bureaucracy cost が厳しい世界である。

● cdfSync システム:NetCDF の更新部分だけを伝送するシステム

Rsync アルゴリズム (Tridgell, 2003) に基づく。クライアントはファイルをブロックに分解しハッシュシグネチャを計算し、それをサーバに転送。強(MD4)弱(rolling)のハッシュを計算。弱ハッシュは高速に計算できる。サーバ側では弱ハッシュを計算して差分を検出する(強ハッシュの使いかたがよくわからない)。

我々のすごいこと。NetCDF のブロックを活用。ファイル数が多い場合に対応するためにヘッダ圧縮:10^6ファイル程度。巨大ファイルの一部更新ならコピーを作らない in-place update(Con: 失敗したらファイルは壊れる;順番の入れ替えがあった場合を検出しなくてはいけない)。

●ベン・ドメニコの高尚な話し

シンクライアント対重厚クライアントの話。とくに方向性は示していない。

今の技術的チャレンジ: (1) 多様なプロトコル OpenDAP, ADDE, OGC WCS をいかに統合するか、多様なデータのカタログ THREDDS, CSW をいかに統合するか、(2) メタデータの発見と利用 (3) サーバーサイトでのデータの永続的保存、いいかえると万人が自分の永続的ケーススタディコレクションを作れるわけではない問題 (4) ローカルアプリケーションをWebのリンクから起動する方法(MIMEタイプ)

(3) については、クライアントのディスクを如何に有効活用するかが鍵になるのだと思う。データが一部無くなっても構わないようなものであるのなら、システムを P2P 化して利用者のダウンロードしたデータを強制的にネットワークでサービスするようにすれば、皆がダウンロードしたがるようなデータは実質的に消えることがない、というようなものが一案かもしれない。これがうまくできれば、だいぶん世の中変わると思う。

(4) については、要するに好き勝手なファイルフォーマットを作るのは善いが、ブラウザからプラグインで呼び出すビューワがないので、いつまで立っても画像ファイルにとらわれていて面白くないねえ、という感じかな。では画像ではなく、何を追求するのかと考えれば、画像としてのデータという発想にならざるを得ないと思うのだが。

FC2Ad

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