tkcif.py Library Technical Documentation

ライブラリの機能や目的

tkcif.py ライブラリは、Crystallographic Information File (CIF) の解析と管理を目的としています。このライブラリは、CIFファイルから結晶構造情報を抽出し、Pythonオブジェクト (tkCIFDatatkCrystal) として表現することで、プログラムによる結晶データのアクセス、操作、および再保存を容易にします。

主な機能は以下の通りです。

  • CIFファイルの読み込み: 単一または複数のデータブロックを含むCIFファイルを読み込み、解析します。

  • CIFデータ構造の解析: キーワードと値のペア、ループ構造、コメントなど、CIFファイルの複雑な構文を解析し、Pythonの辞書形式に変換します。

  • 結晶構造オブジェクトへの変換: 解析されたCIFデータから、tklib.tkcrystal.tkcrystal パッケージの tkCrystal オブジェクトを生成し、結晶学的なプロパティにアクセスできるようにします。

  • CIFファイルの書き出し: 結晶構造オブジェクトからCIF形式のファイルを再生成する機能を提供します。

このライブラリは、結晶学研究や材料科学分野でのデータ処理、シミュレーション前処理、結果の可視化など、CIFデータをプログラムで扱う必要があるシナリオで役立ちます。

importする方法

tkcif.py ライブラリは、以下の方法で他のPythonプログラムからインポートできます。

# tkCIF クラスを直接インポートする場合
from tkcif import tkCIF

# ライブラリ全体をインポートし、tkcif.tkCIF としてアクセスする場合
import tkcif

必要な非標準ライブラリとインストール方法

tkcif.py は、内部で tklib パッケージに属する様々なモジュールを利用しています。 この tklib パッケージは標準ライブラリではないため、別途インストールが必要です。

必要な非標準ライブラリ:

  • tklib: tkobject, tkcrystal.tkcifobject, tkcrystal.tkcrystal, tkutils, tkfile, tkre などのモジュールを提供します。

インストール方法:

tklib パッケージが公開されている場合、通常は pip コマンドを使用してインストールできます。

pip install tklib

もし tklib がPyPIなどの公開リポジトリにない場合は、別途提供されるインストール手順に従うか、ソースコードを適切な場所に配置してPythonのパスが通るように設定する必要があります。

標準ライブラリ: 以下のライブラリはPythonの標準ライブラリに含まれているため、別途インストールは不要です。

  • sys

  • shlex

  • re

  • pprint

importできる変数と関数

変数(モジュールレベルの定数)

tkcif.py をインポートすると、CIFデータのパース状態を示す以下の定数が利用可能です。これらの定数は、主に tkCIF クラスの GetNextKey メソッドによって返されるステータス値として使用されます。

  • end_of_cifdata (int): CIFデータの終端を示す。値は 0

  • header (int): データブロックのヘッダー (data_...) を示す。値は 1

  • comment (int): コメント行 (#) を示す。値は 2

  • singlekey (int): 単一のキーワードと値のペア (_keyword value) を示す。値は 3

  • multikeys (int): 複数行にわたる値、または1行に複数の値を持つキーワード (value1 value2 ...) を示す。値は 4

  • loopkeys (int): loop_ 構造内のキーワードと値のブロックを示す。値は 5

  • other (int): その他の、または未定義の行タイプを示す。値は 999

クラス

tkCIF(tklib.tkcrystal.tkcifobject.tkCIFObject)

CIFファイル(Crystallographic Information File)を管理するための主要なクラスです。tklib.tkcrystal.tkcifobject.tkCIFObject を継承しており、ファイルI/OおよびCIFオブジェクトの基本的な機能を提供します。

コンストラクタ:

  • __init__(self, path=None, mode='r', **args)

    • 動作: tkCIF オブジェクトを初期化します。指定されたパスのファイルを指定されたモードで開きます。

    • 引数:

      • path (str, optional): 開くCIFファイルのパス。省略された場合は、後で Open() メソッドを使用してファイルを開くか、既に開かれているファイルポインタを使用します。

      • mode (str, optional): ファイルのオープンモード(例: 'r' 読み込みモード、'w' 書き込みモード)。デフォルトは 'r'

      • **args: 親クラスのコンストラクタに渡される追加のキーワード引数。

    • 戻り値: なし。

デストラクタ:

  • __del__(self)

    • 動作: オブジェクトが破棄される際に、開いているファイルを閉じます。

    • 引数: なし。

    • 戻り値: なし。

文字列表現:

  • __str__(self)

    • 動作: オブジェクトのクラスパスを文字列で返します。

    • 引数: なし。

    • 戻り値: str - クラスの完全パス(例: 'tklib.tkcif.tkCIF')。

メソッド:

  • splitline(self, lines, i)

    • 動作: lines リストの i 番目の行を、キーワードと値に分割します。空白区切りを基本としますが、キーワードが空でない場合は最初の空白区切りまでをキーワードとし、残りを値とします。

    • 引数:

      • lines (list of str): 解析対象の行のリスト。

      • i (int): lines リスト内の行のインデックス。

    • 戻り値: tuple - (line, keyword, value)

      • line (str): 元の行。

      • keyword (str): 行から抽出されたキーワード。

      • value (str): キーワード以降の値部分。

  • GetNextValuesOne(self, lines, nrequired, i)

    • 動作: lines リストの i 番目の行からCIF値を抽出します。単一行または複数行にわたる値の解析に対応しています。

    • 引数:

      • lines (list of str): 解析対象の行のリスト。

      • nrequired (int): 期待される値の数。

      • i (int): 解析を開始する lines リストのインデックス。

    • 戻り値: tuple - (c, status, retline, retval)

      • c (int): 次に読み取るべき行のインデックス。

      • status (int): 読み込んだ値のタイプ(singlekey, multikeys, end_of_cifdata など)。

      • retline (str): 抽出された値を含む元の行(または複数行を結合したもの)。

      • retval (list of str): 抽出された値のリスト。

  • GetNextValues(self, lines, nrequired, i)

    • 動作: lines リストの i 番目の行から複数行にわたるCIF値を抽出し、nrequired 個の値が見つかるまで読み込みを続けます。

    • 引数:

      • lines (list of str): 解析対象の行のリスト。

      • nrequired (int): 期待される値の総数。

      • i (int): 解析を開始する lines リストのインデックス。

    • 戻り値: tuple - (c, status, retline, retval)

      • c (int): 次に読み取るべき行のインデックス。

      • status (int): 読み込んだ値のタイプ(multikeys, end_of_cifdata など)。

      • retline (str): 抽出された値を含む元の行を結合したもの。

      • retval (list of str): 抽出された値のリスト。

  • GetNextKey(self, lines, i)

    • 動作: lines リストの i 番目の行から次のCIFキーワードとその値の情報を抽出します。ヘッダー、コメント、単一キーワード、ループ構造などを識別します。

    • 引数:

      • lines (list of str): 解析対象の行のリスト。

      • i (int): 解析を開始する lines リストのインデックス。

    • 戻り値: tuple - (c, status, keyval)

      • c (int): 次に読み取るべき行のインデックス。

      • status (int): 読み込んだキーワードのタイプ(end_of_cifdata, header, comment, singlekey, loopkeys, other)。

      • keyval (list): 抽出されたキーワードと値のリスト。

        • header: ['header', 'data_block_name']

        • comment: ['# comment text', '']

        • singlekey: ['_keyword', 'value']

        • loopkeys: [[['_kw1','val1a'],['_kw2','val2a']], [['_kw1','val1b'],['_kw2','val2b']]] のようなリストのリスト。

        • other: ['problematic line content', '']

  • StringsToCIF(self, lines)

    • 動作: lines リスト(CIFデータブロックの文字列リスト)を解析し、CIFコンテンツをキーと値の辞書形式に変換します。ループ構造のデータは、キーワードにインデックスを付加した形式(例: _atom_site_label[0], _atom_site_label[1]) で格納されます。

    • 引数:

      • lines (list of str): ReadNextCIF などで読み込まれたCIFデータブロックの行のリスト。

    • 戻り値: dict - cifinf[keyword] = value の形式でCIFコンテンツを格納した辞書。

  • ReadNextCIF(self, path=None, print_level=0)

    • 動作: ファイルポインタから次のCIFデータブロックを読み込み、その内容を行のリストとして返します。data_ で始まる次のヘッダー、または #End で終わるまでを1つのブロックと見なします。

    • 引数:

      • path (str, optional): 読み込むCIFファイルのパス。この引数が与えられた場合、この関数内でファイルをオープン・クローズします。省略された場合は、オブジェクトに既に設定されている self.path を使用します。

      • print_level (int, optional): デバッグ出力のレベル。デフォルトは 0

    • 戻り値: list of str - 次のCIFデータブロックの行のリスト。読み込むデータがもうない場合は None を返します。

  • __ReadCIF1(self, path=None, print_level=1)

    • 動作: 単一のCIFデータブロックを読み込み、tkCIFData オブジェクトとして返します。これは read_cif メソッドから内部的に呼び出されるヘルパー関数です。

    • 引数:

      • path (str or io.StringIO, optional): 読み込むCIFファイルのパス、またはStringIOオブジェクト。

      • print_level (int, optional): デバッグ出力のレベル。デフォルトは 1

    • 戻り値: tklib.tkcrystal.tkcifobject.tkCIFData - 読み込まれたCIFデータを格納するオブジェクト。

  • read_cif(self, path=None, find_valid_structure=1, print_level=1)

    • 動作: CIFファイルを読み込み、tkCIFData オブジェクトとして返します。find_valid_structure1 の場合、有効な結晶構造データ (_cell_length_a\(0\) より大きい) を持つ最初のブロックを探して返します。それ以外の場合は、最初のブロックのみを読み込みます。

    • 引数:

      • path (str or io.StringIO, optional): 読み込むCIFファイルのパス、またはStringIOオブジェクト。

      • find_valid_structure (int, optional): 有効な構造が見つかるまで読み込みを続けるかどうかのフラグ。1 で続ける、0 で最初のブロックのみ。デフォルトは 1

      • print_level (int, optional): デバッグ出力のレベル。デフォルトは 1

    • 戻り値: tklib.tkcrystal.tkcifobject.tkCIFData - 読み込まれたCIFデータを格納するオブジェクト。有効な構造が見つからない場合は None

  • ReadCIF(self, path=None, find_valid_structure=1, print_level=1)

    • 動作: read_cif メソッドのエイリアスです。

    • 引数: read_cif と同じ。

    • 戻り値: read_cif と同じ。

  • ReadCIFs(self, path=None, print_level=1)

    • 動作: CIFファイルを読み込み、ファイル内のすべてのデータブロックを tkCIFData オブジェクトのリストとして返します。

    • 引数:

      • path (str or io.StringIO, optional): 読み込むCIFファイルのパス、またはStringIOオブジェクト。

      • print_level (int, optional): デバッグ出力のレベル。デフォルトは 1

    • 戻り値: list of tklib.tkcrystal.tkcifobject.tkCIFData - 読み込まれたすべてのCIFデータブロックを格納するオブジェクトのリスト。

関数

main()

  • 動作: スクリプトが直接実行された場合に呼び出されるメイン関数です。test.cif ファイルを読み込み、CIFデータの表示、結晶構造オブジェクトの生成、および変換されたCIFファイルの書き出しを行います。single フラグによって単一のデータブロックを扱うか、複数のデータブロックを扱うかを切り替えます。

  • 引数: なし。

  • 戻り値: なし。

main scriptとして実行したときの動作

tkcif.py ファイルをPythonインタプリタで直接実行した場合 (python tkcif.py)、main() 関数が呼び出されます。

  1. infile の設定: infile 変数は 'test.cif' に初期設定されます。スクリプトに引数が与えられた場合(例: python tkcif.py my_data.cif)、その引数が infile として使用されることがコメントアウトされたコードで示唆されていますが、現在のコードでは常に 'test.cif' を使用します。

  2. tkCIF オブジェクトの生成: tkCIF(infile) を使用して tkCIF オブジェクト cif を作成します。

  3. デバッグレベルの設定: cif.debug = debug が実行されます。ただし、現在のコードではグローバルスコープに debug 変数が定義されていないため、この行は NameError を発生させます。もしdebugが定義されていると仮定すると、その値でデバッグ出力レベルが設定されます。

  4. CIFデータの読み込みと処理:

    • single 変数が 1 に設定されているため、単一のCIFデータブロックを処理するパスが実行されます。

    • cif.ReadCIF() を呼び出し、最初の有効なCIFデータブロックを cifdata オブジェクトとして読み込みます。

    • cifdata.Print() を呼び出し、読み込んだCIFデータを標準出力に表示します。

    • cifdata.GetCrystal() を呼び出し、CIFデータから tkCrystal オブジェクト cry を生成します。

    • cry.PrintInf() を呼び出し、生成された結晶構造の情報を標準出力に表示します。

    • cifdata.WriteSimpleCIFFile('a.cif') を呼び出し、読み込んだCIFデータを簡易形式で a.cif というファイルに書き出します。

    • cifdata.CreateCIFFileFromCCrystal(cry, 'b.cif') を呼び出し、生成された tkCrystal オブジェクトから b.cif というファイルにCIFデータを書き出します。

    • もし single0 (False) に設定されている場合、cif.ReadCIFs() が呼び出され、ファイル内のすべてのCIFデータブロックを tkCIFData オブジェクトのリストとして読み込み、それぞれの内容を Print() で表示します。

  5. ファイルクローズ: 最後に cif.Close() を呼び出し、開いているファイルを閉じます。

注意点:

  • 現在のソースコードをそのまま実行すると、debug 変数が未定義であるため NameError が発生します。これを回避するには、main 関数内で debug = 0 のように変数を定義する必要があります。

  • 実行には、test.cif というファイルがスクリプトと同じディレクトリに存在する必要があります。存在しない場合、ファイル読み込みエラーが発生します。

  • tklib パッケージが正しくインストールされている必要があります。