Home
1050 words
5 minutes
【計算化学】ブログ記事の遷移状態構造の虚振動のアニメーション生成pythonスクリプト

最終更新:2025-12-15

過去の記事の抜粋である。ブログ記事の遷移状態構造の虚振動のアニメーション生成を手元で行うのに便利なスクリプトを置いておく。

python 3.ⅹASE, numpyさえあれば動くはずである。

以下、遷移状態構造。

migratory_insertion_Rh_AsCF3_3_2_C2H4_ts_final_1.xyz

36
OptimizedStructure
Rh     0.958151914527      0.092523108800     -0.496769592729
H      1.501231121468      0.233108056765      1.040216302151
C      0.803480069587      0.104833433532     -2.416926942935
O      0.758192356809      0.122464408665     -3.548518032566
C      2.957005795567     -0.071699319221      0.623941487154
C      3.057874755464     -0.445802496509     -0.729739370779
H      3.022748919493     -0.848155772730      1.377973175995
H      3.343837828960      0.888100430758      0.943161677199
H      3.157582137572     -1.494776133770     -0.974477842407
H      3.516335870909      0.242389745586     -1.426046401644
As    -0.313784781338      2.017271125955      0.004136565475
As    -0.356475336740     -1.870936669561      0.017863940241
C     -0.422505248928      2.661070244596      1.889689280198
C      0.114783787530      3.769208436270     -0.859021574324
C     -2.269670013406      1.986906003723     -0.414933185319
C     -1.201087816673     -2.163146686806      1.804168903202
C     -1.941297149575     -2.344805908135     -1.103865962241
C      0.590904845605     -3.629162849501     -0.096200561111
F      0.721718877363      3.295304871851      2.189296157545
F     -1.434674440222      3.497707979413      2.120392993993
F     -0.549064186420      1.618346939271      2.715745543089
F      1.439811460481      3.959175262177     -0.830109288397
F     -0.464149686809      4.829257365032     -0.294327436700
F     -0.269539766699      3.714827497028     -2.143395154607
F     -2.857245270090      3.181479027595     -0.466811224298
F     -2.441792355518      1.388126816966     -1.602141526104
F     -2.889919911077      1.250495486638      0.516776489532
F     -2.995969850986     -1.629128176519     -0.692401633655
F     -1.684258200831     -2.011037052301     -2.376195287556
F     -2.275270870868     -3.635492673751     -1.078865165524
F     -0.233874685999     -2.442850228712      2.693110590351
F     -1.805493042457     -1.034568429608      2.190787492883
F     -2.100283123568     -3.147087897264      1.845131722467
F      1.789684893939     -3.500540661486      0.498686217354
F      0.805876262244     -3.921718800742     -1.388218246484
F     -0.032865159314     -4.661686484001      0.467885890551
遷移状態構造 (No.1)

以下に虚振動を可視化するスクリプトを示す。遷移状態構造をxyzファイルに保存し、以下のスクリプトをコピーして同じディレクトリ内で実行すると虚振動のアニメーションが見られるxyzファイルが出力される。ほかのブログ記事の内容に対しても、このスクリプトのLOG_TEXTの改変および対応する遷移状態構造を保存すればアニメーションを生成可能である。

import numpy as np
from ase.io import read, write

# ---------------------------------------------------------
# 1. ブログの「Normal Mode」セクションをここにコピペします
# ---------------------------------------------------------
LOG_TEXT = """
Mode                      0                   1                   2
Freq [cm^-1]          -909.3347              12.0385             20.0676
Reduced mass [au]        1.1783              12.0872             16.8805
Force const [Dyne/A]    -0.5740               0.0010              0.0040
Char temp [K]            0.0000              17.3207             28.8727
Normal mode           x       y       z            x       y       z            x       y       z      
     Rh          0.00293   -0.00230   -0.00896    -0.00926    0.00045   -0.02268    -0.00019   -0.00091   -0.00418
      H          0.87899    0.05212   -0.11058     0.02243    0.00304   -0.03452     0.01531    0.00033   -0.00932
      C          0.01400    0.01538    0.01514    -0.04773    0.00352   -0.02005    -0.01983   -0.00649   -0.00226
      O         -0.00096   -0.00249    0.00893    -0.06969    0.00654   -0.01910    -0.03206   -0.01067   -0.00184
      C         -0.06931    0.02242    0.05233     0.01506   -0.00373   -0.06656     0.00955   -0.00410   -0.02215
      C         -0.05206   -0.00050   -0.02231    -0.01787   -0.01605   -0.06534    -0.00271   -0.00187   -0.02381
      H          0.13267   -0.01656    0.00744     0.02788    0.00246   -0.06133     0.01516   -0.00563   -0.02421
      H          0.13983   -0.04034    0.01118     0.02615   -0.00262   -0.08352     0.01449   -0.00548   -0.02397
      H          0.06118   -0.00128    0.03012    -0.02993   -0.01877   -0.05877    -0.00560   -0.00151   -0.02640
      H          0.05826   -0.01582    0.03660    -0.02992   -0.02492   -0.08204    -0.00815   -0.00101   -0.02653
     As         -0.00179   -0.00155    0.00138     0.00204    0.00071    0.00173     0.00333    0.00115   -0.00346
     As         -0.00089    0.00009    0.00183     0.00015   -0.00006    0.00261     0.00085    0.00164    0.00883
      C         -0.00298    0.00417   -0.00256     0.00309   -0.02263    0.00984    -0.03789   -0.01174   -0.00128
      C          0.00115   -0.00142   -0.00063     0.01341    0.01062    0.02732     0.02421    0.00861    0.02223
      C          0.00029    0.00168    0.00034     0.00329    0.01577   -0.00479     0.01253    0.00225   -0.04520
      C         -0.00306   -0.00517   -0.00363    -0.01986    0.01732   -0.00375     0.02780   -0.00554    0.02013
      C          0.00066    0.00029    0.00027     0.01713   -0.02674   -0.00965    -0.01831    0.00844    0.03276
      C         -0.00097    0.00115   -0.00059     0.01475    0.00549    0.03854    -0.00214    0.00161   -0.01713
      F          0.00099    0.00001    0.00045     0.00202   -0.02379    0.01617    -0.04936   -0.00400    0.02553
      F         -0.00114    0.00148    0.00298     0.00146   -0.02752    0.02063    -0.04969   -0.02141   -0.01701
      F          0.00083   -0.00036   -0.00101     0.00627   -0.03257   -0.00242    -0.04584   -0.01754   -0.01019
      F          0.00044   -0.00049    0.00030     0.01440    0.00306    0.03299     0.02323    0.01025    0.06157
      F          0.00035   -0.00125   -0.00005     0.01783    0.00559    0.04140     0.00661    0.00343    0.01393
      F          0.00000   -0.00017    0.00011     0.01595    0.03126    0.02574     0.06100    0.01808    0.01085
      F         -0.00151    0.00063   -0.00030     0.00982    0.01959    0.00934     0.01379    0.00208   -0.06044
      F          0.00022    0.00019   -0.00004     0.00440    0.03274   -0.01358     0.03718   -0.00057   -0.04754
      F          0.00065    0.00044    0.00003    -0.00388    0.00630   -0.01725    -0.00708    0.00406   -0.05658
      F          0.00008   -0.00023   -0.00001     0.01082   -0.01846   -0.03972    -0.01179    0.00481    0.05563
      F          0.00004    0.00020   -0.00014     0.03410   -0.05411   -0.01346    -0.04066    0.01679    0.03051
      F         -0.00017    0.00013    0.00001     0.01793   -0.02642    0.01362    -0.01692    0.00796    0.03050
      F          0.00037    0.00023   -0.00035    -0.02824    0.04209    0.01293     0.04311    0.00825    0.00791
      F          0.00035   -0.00085   -0.00026    -0.03815    0.01612   -0.02901     0.01890   -0.01201    0.02517
      F         -0.00317   -0.00247    0.00348    -0.00916    0.00762   -0.00040     0.04047   -0.01646    0.03456
      F          0.00008    0.00024    0.00021     0.00744    0.02352    0.04966     0.00822   -0.00233   -0.03706
      F          0.00034   -0.00010   -0.00003     0.03126   -0.01172    0.04512    -0.02456    0.00945   -0.02267
      F          0.00024   -0.00018    0.00014     0.01688    0.00872    0.04670     0.00754   -0.00164   -0.01257
"""
# ---------------------------------------------------------

def parse_mode0_vectors(text):
    """ログテキストからMode 0 (虚振動) のベクトルを抽出する"""
    vectors = []
    for line in text.strip().split('\n'):
        parts = line.split()
        
        # 数が少なすぎる、または "Mode" で始まる行はヘッダーなのでスキップ
        if len(parts) < 4 or parts[0] == "Mode":
            continue
            
        try:
            # 2, 3, 4列目(index 1, 2, 3)が数値に変換できればベクトルとみなす
            # Mode 0 (x, y, z)
            vec = [float(parts[1]), float(parts[2]), float(parts[3])]
            vectors.append(vec)
        except ValueError:
            # ヘッダー行(Freq, Massなど)はここで弾かれるので無視してOK
            continue
    return np.array(vectors)

def generate_animation(structure_file, vectors, output_file="imaginary_mode.xyz", frames=20, amp=1.5):
    """構造とベクトルからアニメーションXYZを生成"""
    atoms = read(structure_file)
    initial_pos = atoms.get_positions()
    
    if len(initial_pos) != len(vectors):
        print(f"Error: 原子数({len(initial_pos)})とベクトルの行数({len(vectors)})が一致しません。")
        print("ヒント: LOG_TEXTのコピペ範囲が正しいか、または不要な行が含まれていないか確認してください。")
        return

    images = []
    for i in range(frames):
        phase = 2 * np.pi * i / frames
        # sin波で振動させる
        new_atoms = atoms.copy()
        new_atoms.set_positions(initial_pos + vectors * np.sin(phase) * amp)
        images.append(new_atoms)
    
    write(output_file, images)
    print(f"Animation saved to: {output_file}")

if __name__ == "__main__":
    # 構造ファイル名を指定してください
    xyz_filename = "migratory_insertion_Rh_AsCF3_3_2_C2H4_ts_final_1.xyz"
    
    # パース実行
    mode0_vectors = parse_mode0_vectors(LOG_TEXT)
    
    # アニメーション生成
    generate_animation(xyz_filename, mode0_vectors, amp=2.0)
【計算化学】ブログ記事の遷移状態構造の虚振動のアニメーション生成pythonスクリプト
https://ss0832.github.io/posts/20251215_imaginary_freq_animation/
Author
ss0832
Published at
2025-12-15