CrystFEL で指数付け・積分して得られた反射強度を、cctbx.xfel に含まれる cxi.postrefine でスケールしてみようとした。CrystFEL 付属の partialator がまだ experimental な段階であり、ほとんどのフレームで最適化が発散してしまうためだ。その理由は、結晶方位と格子定数を同時に最適化しようとしているかららしい。しかも、Bravais lattice による constraint もかかっていない。
前置きはともかく、cxi.index などが作る pickle ファイルと同じものを作ればよいはず。cxi/postrefine/postrefine.py や cxi/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 で処理したい場合は、さらなる工夫が必要。別稿を待たれよ。