# tkcif マニュアル

## 1. 役割

`tkcif` は、CIFを単一のreaderに固定せず、複数backendを順番に試して**可能な限り `pymatgen.Structure` を得る**ための互換・正規化レイヤーです。壊れ気味のCIFに対しては、構文正規化、ASE経由、旧 `tkCIF` 経由をfallbackとして使います。

## 2. 推奨import

現在の `tkcif/__init__.py` は公開関数を再exportしていません。次のモジュールimportを使ってください。

```python
from tkcif.tkcif_reader import (
    CIFReadError,
    CIFReadInfo,
    read_structure,
    read_ase_atoms,
    read_tkcrystal,
    normalize_cif,
)
```

`from tkcif import read_structure` は現状のソースでは使えません。

## 3. 最小例

```python
from tkcif.tkcif_reader import read_structure

structure, info = read_structure("sample.cif", return_info=True)
print(structure.formula)
print(info.backend)
print(info.short_report())
```

通常は `primitive=False` のままにして、CIFに書かれたセルを保持します。

## 4. `read_structure()` のfallback順序

既定順序は次です。

1. `pymatgen`: pymatgenで直接読む
2. `tkcif_base+pymatgen`: `tkcif_normalize.py` で正規化してからpymatgenで読む
3. `ase+pymatgen`: ASEで読み、`pymatgen.Structure`へ変換
4. `tkcif_legacy+pymatgen`: 旧 `tkCIF` → `tkCrystal` → `pymatgen.Structure`

特定backendだけを試す場合:

```python
structure, info = read_structure(
    "sample.cif",
    return_info=True,
    backend_order=["tkcif_base+pymatgen", "ase+pymatgen"],
)
```

すべて失敗すると `CIFReadError` が発生し、試行backendと各エラーがメッセージに含まれます。

## 5. 診断情報 `CIFReadInfo`

主要フィールド:

| フィールド | 内容 |
|---|---|
| `path` | 入力CIFパス |
| `backend` | 成功したbackend |
| `attempted_backends` | 試行したbackend一覧 |
| `unavailable_backends` | 未導入・利用不能backend |
| `errors` | 読み込み失敗の要約 |
| `warnings` | parser警告 |
| `normalized` | 正規化を経由したか |
| `encoding` | 推定された文字コード |
| `fallback_object` | ASE Atomsまたは旧tkCrystalの参照 |

`return_info=True` は、研究データの再現性確保や大量処理時のログ保存に推奨です。

## 6. ASEまたは旧tkCrystalを直接得る

```python
from tkcif.tkcif_reader import read_ase_atoms, read_tkcrystal

atoms = read_ase_atoms("sample.cif")
legacy_crystal = read_tkcrystal("sample.cif")
```

これらはpymatgenに依存しない診断経路です。`read_tkcrystal()` のlegacy module候補は `module_candidates=` で上書きできます。

## 7. CIF正規化

```python
from tkcif.tkcif_reader import normalize_cif

normalized_text, document, warnings, encoding = normalize_cif("broken.cif")
```

ファイルとして正規化する低レベルAPIは `tkcif.tkcif_normalize.normalize_cif_file()` です。正規化層は、空白・改行・引用・loop・複数行text fieldなどをlenientに処理しますが、**結晶学的妥当性を保証するものではありません**。

## 8. 構造変換ヘルパー

- `ase_atoms_to_pymatgen_structure(atoms)`
- `tkcrystal_to_pymatgen_structure(cry)`

旧 `tkCrystal` の具体的な属性構造が環境ごとに異なる場合、後者のadapter調整が必要です。

## 9. サマリー生成

```python
from tkcif.tkcif_reader import structure_summary_text

print(structure_summary_text(structure, symprec=1.0e-3))
```

ASEと旧tkCrystalにも、それぞれbest-effortのサマリー関数があります。

## 10. CLI

```bash
python -m tkcif.cif_inf_reader sample.cif
python -m tkcif.cif_inf_reader sample.cif --reader ase
python -m tkcif.cif_inf_reader sample.cif --reader tkcrystal
```

## 11. 依存関係

- 主backend: `pymatgen`
- optional fallback: `ase`
- legacy fallback: 旧 `tkCIF` / `tkCrystal` 実装
- 正規化コア: 標準ライブラリ中心

## 12. 生成AI向けコード生成ルール

1. 既定の戻り値は `pymatgen.Structure` とし、辞書やASE Atomsと誤認しない。
2. 読み込み経路を記録する必要があるコードでは必ず `return_info=True` を使う。
3. `tkcif` トップレベルから関数をimportせず、`tkcif.tkcif_reader` を使う。
4. CIF読込失敗を単純な `FileNotFoundError` だけと仮定せず、`CIFReadError` を扱う。
5. 正規化は構文補正であり、占有率、空間群、組成、密度の物理的妥当性検証とは分ける。
6. 旧tkCrystal adapterの属性名を推測で決めない。対象実装を確認してから変更する。
