CrystFEL の stream を cctbx.xfel 用の pickle ファイルに変換する (未完成)

CrystFEL で指数付け・積分して得られた反射強度を、cctbx.xfel に含まれる cxi.postrefine でスケールしてみようとした。CrystFEL 付属の partialator がまだ experimental な段階であり、ほとんどのフレームで最適化が発散してしまうためだ。その理由は、結晶方位と格子定数を同時に最適化しようとしているかららしい。しかも、Bravais lattice による constraint もかかっていない。

前置きはともかく、cxi.index などが作る pickle ファイルと同じものを作ればよいはず。cxi/postrefine/postrefine.pycxi/postrefine/mod_leastsqr.py を見ながら、必要なフィールドを確認する。データの型は、cctbx.python で実際に

from cctbx.array_family import flex
from cctbx import miller
import cPickle as pickle

int=pickle.load(open("int_test.pickle"))
int['observations'][0].d_max_min()
int['wavelength']

などとやりながら調査した。

その結果、以下のコンバータができた。
→8/19 GitHub にアップロードしたので、ブログからはコードを削除。https://github.com/biochem-fan/CrystFEL/ の experimental branch の scripts/ フォルダを参照。

まず、スポットの検出器上での場所(ピクセル単位)が必要となるのだが、stream にあるのはパネルの geometry を考慮していない、HDFファイル上での論理的なピクセル位置なので、libcrystfel を使って物理座標に変換する。それが1つ目の C コード。

つぎに、その出力をもとに、Python オブジェクトを組み立てて pickle にシリアライズするのが Python コード。

これらを組み合わせて

./export_to_pickle cspad.geom processed.stream | cctbx.python export_to_pickle.py

などとすると、カレントディレクトリに大量の連番 pickle ファイルができるので、これを昨日書いたように cxi.postrefine で処理すればよい。

ただし、post-refinement 自体は安定しているようだが、結果がどうもおかしい。上の変換方法があっているという保証はないので、これを土台に試行錯誤していただきたい。随時アップデートする予定。

注意点:
波長は stream ファイルにあるのだが、libcrystfel が読み込んでくれないので、とりあえず python 側で固定している。本当は libcrystfel の stream.c を改造するべき。 ←8/19追記: 波長の単位が Å じゃなくて m なので 0 に見えただけだった。

また、空間群も python 側で決め打ちしてしまった。

cxi.merge で処理したい場合は、さらなる工夫が必要。別稿を待たれよ。