Cayley–Menger
いいね、「じゃあもう自分で回すか」のフェーズに来たね。 Cayley–Menger を Python で自動化する最小セットを、距離ファイルから回せる形で出すよ。
1. 四面体の Cayley–Menger 体積関数(距離だけでOK)
python
import numpy as np
def tetra_volume_from_dist(d12, d13, d14, d23, d24, d34):
# Cayley–Menger 行列
cm = np.array([
[0, 1, 1, 1, 1],
[1, 0, d12**2, d13**2, d14**2],
[1, d12**2, 0, d23**2, d24**2],
[1, d13**2, d23**2, 0, d34**2],
[1, d14**2, d24**2, d34**2, 0]
], dtype=float)
det = np.linalg.det(cm)
# 数値誤差で負になることがあるので max(…, 0)
V2 = det / 288.0
return np.sqrt(max(V2, 0.0))
これで 6本の距離 → 四面体体積 が一発で出る。
2. 六面体(12辺立体)を「5つの四面体」に分けて足し合わせる
例えば頂点を A,B,C,D,E,F,G,H として、 六面体をこう分割するとする:
四面体1:A, B, C, E
四面体2:B, C, E, F
四面体3:C, E, F, G
四面体4:E, F, G, H
四面体5:A, E, G, H
あとは それぞれの 6 本の距離を tetra_volume_from_dist に入れて足すだけ。
python
def hexa_volume_from_all_dist(dist):
"""
dist[(i, j)] = 距離
i, j は 'A','B','C','D','E','F','G','H' などのラベル
"""
def d(i, j):
return dist[tuple(sorted((i, j)))]
V1 = tetra_volume_from_dist(d('A','B'), d('A','C'), d('A','E'),
d('B','C'), d('B','E'), d('C','E'))
V2 = tetra_volume_from_dist(d('B','C'), d('B','E'), d('B','F'),
d('C','E'), d('C','F'), d('E','F'))
V3 = tetra_volume_from_dist(d('C','E'), d('C','F'), d('C','G'),
d('E','F'), d('E','G'), d('F','G'))
V4 = tetra_volume_from_dist(d('E','F'), d('E','G'), d('E','H'),
d('F','G'), d('F','H'), d('G','H'))
V5 = tetra_volume_from_dist(d('A','E'), d('A','G'), d('A','H'),
d('E','G'), d('E','H'), d('G','H'))
return V1 + V2 + V3 + V4 + V5
3. ChimeraX の pairdist 出力をそのまま食わせる
pairdist sel save distances.txt の出力を 例えばこんな感じで読めばいい:
python
def load_pairdist_file(path):
dist = {}
with open(path) as f:
for line in f:
# 行の形式に合わせてパースする
# 例: "A@CA B@CA 3.456"
parts = line.split()
if len(parts) < 3:
continue
atom1, atom2, dval = parts[0], parts[1], float(parts[-1])
# ここで 'A','B','C' などにマッピングする
# 例: atom1 が "#1:A" ならラベル 'A' にする、など
# label1, label2 = ...
# dist[(min(label1,label2), max(label1,label2))] = dval
return dist
あとは:
python
dist = load_pairdist_file("distances.txt")
V = hexa_volume_from_all_dist(dist)
print("Pocket volume =", V)
一行でまとめると
Cayley–Menger の自動化は 「pairdist で距離を吐く → Python で Cayley–Menger → 四面体を足して六面体体積」 の3ステップで、もうほぼ完成している。
ここまで来ると、 「ポケットを6点で定義して体積を数値化する」世界、 本当にすぐそこだよ。
2026年6月28日 | カテゴリー:物理数学統計諸計算 |




