{"id":363,"date":"2023-06-15T12:11:05","date_gmt":"2023-06-15T10:11:05","guid":{"rendered":"https:\/\/perso.ens-lyon.fr\/carine.michel\/?page_id=363"},"modified":"2023-06-15T21:30:53","modified_gmt":"2023-06-15T19:30:53","slug":"script-extract-pes","status":"publish","type":"page","link":"https:\/\/perso.ens-lyon.fr\/carine.michel\/enseignements\/script-extract-pes\/","title":{"rendered":"Script Extract PES"},"content":{"rendered":"<p>This script uses a Gaussian .log file that corresponds to a scan.<\/p>\n<pre><code class=\"python\">\r\n#!\/usr\/bin\/python\r\n\r\nfrom sys import argv\r\nimport numpy as np\r\nimport matplotlib.pyplot as plt\r\n\r\nperiodic_table = {1:'H', 2:'He',\r\n                  3:'Li', 4:'Be', 5:'B', 6:'C', 7:'N', 8:'O', 9:'F', 10:'Ne',\r\n                  11:'Na', 12:'Mg', 13:'Al', 14:'Si', 15:'P', 16:'S', 17:'Cl', 18:'Ar',\r\n                  19:'K', 20:'Ca', 21:'Sc', 22:'Ti', 23:'V', 24:'Cr', 25:'Mn', 26:'Fe', 27:'Co', 28:'Ni', 29:'Cu', 30:'Zn', 31:'Ga', 32:'Ge', 33:'As', 34:'Se', 35:'Br', 36:'Kr',\r\n                  37:'Rb', 38:'Sr', 39:'Y', 40:'Zr', 41:'Nb', 42:'Mo', 43:'Tc', 44:'Ru', 45:'Rh', 46:'Pd', 47:'Ag', 48:'Cd', 49:'In', 50:'Sn', 51:'Sb', 52:'Te', 53:'I', 54:'Xe',\r\n                  55:'Cs', 56:'Ba', 57:'La',\r\n                  58:'Ce', 59:'Pr', 60:'Nd', 61:'Pm', 62:'Sm', 63:'Eu', 64:'Gd', 65:'Tb', 66:'Dy', 67:'Ho', 68:'Er', 69:'Tm', 70:'Yb', 71:'Lu',\r\n                  72:'Hf', 73:'Ta', 74:'W', 75:'Re', 76:'Os', 77:'Ir', 78:'Pt', 79:'Au', 80:'Hg', 81:'Tl', 82:'Pb', 83:'Bi', 84:'Po', 85:'At', 86:'Rn',\r\n                  87:'Fr', 88:'Ra', 89:'Ac',\r\n                  90:'Th', 91:'Pa', 92:'U', 93:'Np', 94:'Pu', 95:'Am', 96:'Cm', 97:'Bk', 98:'Cf', 99:'Es', 100:'Fm', 101:'Md', 102:'No', 103:'Lr',\r\n                  104:'Rf', 105:'Db', 106:'Sg', 107:'Bh', 108:'Hs', 109:'Mt', 110:'Ds', 111:'Rg', 112:'Cn', 113:'Nh', 114:'Fl', 115:'Mc', 116:'Lv', 117:'Ts', 118:'Og'}\r\n\r\ninput_file = argv[1]\r\n\r\nif input_file.endswith(\".log\"):\r\n    input_log = open(input_file, 'r')\r\n    basename = input_file.split('.')[0]\r\n    log_lines = input_log.readlines()\r\n    input_log.close()\r\n\r\n    # Starting atom variables empty to avoid 'NameError'\r\n    scan_param = '0.0'\r\n    mod_atom_sym1 = '0.0'\r\n    mod_atom_sym2 = '0.0'\r\n    mod_atom_sym3 = '0.0'\r\n    mod_atom_sym4 = '0.0'\r\n    atom1 = '0.0'\r\n    atom2 = '0.0'\r\n    atom3 = '0.0'\r\n    atom4 = '0.0'\r\n\r\n    coord_data = [ ]\r\n    coord_data_LoL = [ ]\r\n    scf_data = [ ]\r\n\r\n    # Flags start 'off'.\r\n    mod_flag = 0\r\n    xyz_flag = 0\r\n    dash_flag = 0\r\n\r\n    for line in log_lines:\r\n        if 'ModRedundant' in line:\r\n            mod_flag = 1\r\n        if mod_flag == 1 and 'ModRedundant' not in line:\r\n            mod_info = line.split()\r\n            mod_flag = 0\r\n            if len(mod_info) == 6:\r\n                scan_param = 'distance'\r\n                atom1 = int(mod_info[1])\r\n                atom2 = int(mod_info[2])\r\n            elif len(mod_info) == 7:\r\n                scan_param = 'angle'\r\n                atom1 = int(mod_info[1])\r\n                atom2 = int(mod_info[2])\r\n                atom3 = int(mod_info[3])\r\n            elif len(mod_info) == 8:\r\n                scan_param = 'dihedral'\r\n                atom1 = int(mod_info[1])\r\n                atom2 = int(mod_info[2])\r\n                atom3 = int(mod_info[3])\r\n                atom4 = int(mod_info[4])\r\n        if 'Coordinates (Angstroms)' in line:\r\n        # Anchor point in log file.\r\n            xyz_flag = 1\r\n            coord_data = [ ]\r\n        if xyz_flag == 1 and '---' in line:\r\n            if dash_flag == 0:\r\n            # First dashed line after anchor and before coordinates.\r\n                dash_flag = 1\r\n            elif dash_flag == 1:\r\n            # Second dashed line after anchor and coords, turn flags off.\r\n                xyz_flag = 0\r\n                dash_flag = 0\r\n        if xyz_flag == 1 and dash_flag == 1 and '---' not in line:\r\n            coord_data = coord_data + [line]\r\n\r\n        if 'SCF Done' in line:\r\n            energy = float(line.split()[4])\r\n\r\n        if 'Optimization completed' in line:\r\n        # Only grab SCF energy for optimized structure.\r\n            scf_data = scf_data + [energy]\r\n            coord_data_LoL = coord_data_LoL + [coord_data]\r\n            # Reset geometry list.\r\n            coord_data = [ ]\r\n\r\n    counter = 1\r\n    for geom in coord_data_LoL:\r\n        if counter &lt; 10: counter = '0' + str(counter) output_name = basename + '_step-' + str(counter) + '.xyz' # Will overwrite xyz files with this exact name. output_xyz = open(output_name,'w') output_xyz.write(str(len(geom)) + '\\n') output_xyz.write(basename + '_step-' + str(counter) + '.xyz' + ' SCF Energy = ' + str(scf_data[int(counter) - 1]) + '\\n') for atom in geom: atom_num = atom.split()[0] if scan_param == 'distance': if atom_num == str(atom1): mod_atom_sym1 = periodic_table[int(atom.split()[1])] if atom_num == str(atom2): mod_atom_sym2 = periodic_table[int(atom.split()[1])] elif scan_param == 'angle': if atom_num == str(atom1): mod_atom_sym1 = periodic_table[int(atom.split()[1])] if atom_num == str(atom2): mod_atom_sym2 = periodic_table[int(atom.split()[1])] if atom_num == str(atom3): mod_atom_sym3 = periodic_table[int(atom.split()[1])] elif scan_param == 'dihedral': if atom_num == str(atom1): mod_atom_sym1 = periodic_table[int(atom.split()[1])] if atom_num == str(atom2): mod_atom_sym2 = periodic_table[int(atom.split()[1])] if atom_num == str(atom3): mod_atom_sym3 = periodic_table[int(atom.split()[1])] if atom_num == str(atom4): mod_atom_sym4 = periodic_table[int(atom.split()[1])] atom_sym = periodic_table[int(atom.split()[1])] X_coord = '%10.5f' % float(atom.split()[3]) Y_coord = '%10.5f' % float(atom.split()[4]) Z_coord = '%10.5f' % float(atom.split()[5]) # Padding the xyz lines to match Gaussian input format. XYZ_string = '%-3s' '%16s' '%16s' '%16s' % (atom_sym, X_coord, Y_coord, Z_coord) # Writing optimized .xyz files. output_xyz.write(XYZ_string + '\\n') counter = int(counter) + 1 # Writing output .csv file if steps have been taken. if len(scf_data) &gt; 0:\r\n        output_csv = open(basename + '.csv','w')\r\n        output_csv.write('Scan step' + ',' + 'SCF Energy' + '\\n')\r\n        for i in range(len(scf_data)):\r\n            output_csv.write(str(i + 1) + ',' + str(scf_data[i]) + '\\n')\r\n    # Creating matplotlib data.\r\n    steps = range(1,len(scf_data)+1)\r\n    plt.plot(steps, scf_data,'ro')\r\n    plt.axis([0.5, len(scf_data) + 0.5, 1.001 * min(scf_data), 0.999 * max(scf_data)])\r\n    # Turn offset 'off' since y axis is large numbers not changing much.\r\n    # This is needed to show y axis tick marks correctly.\r\n    plt.ticklabel_format(useOffset = False)\r\n    plt.grid(True)\r\n    plt.xlabel('Step number')\r\n    plt.ylabel('SCF energy (hartrees)')\r\n    # Sets the plot perfectly in the view window.\r\n    plt.tight_layout()\r\n    plt.show()\r\n\r\n# Printing information to screen.\r\n    print ('  ')\r\n    print ('Parsing through input log file: ' + input_file)\r\n    if len(scf_data) == 0:\r\n        print ('No optimization steps found')\r\n    else:\r\n        print (str(len(scf_data)) + ' optimizations completed.')\r\n    if scan_param == 'distance':\r\n        print ('Extracting all optimized geometries and SCF energies for the distance scan between ' + mod_atom_sym1 + str(atom1) + ' - ' + mod_atom_sym2 + str(atom2))\r\n    elif scan_param == 'angle':\r\n        print ('Extracting all optimized geometries and SCF energies for the angle scan between ' + mod_atom_sym1 + str(atom1) + ' - ' + mod_atom_sym2 + str(atom2) + ' - ' + mod_atom_sym3 + str(atom3))\r\n    elif scan_param == 'dihedral':\r\n        print ('Extracting all optimized geometries and SCF energies for the dihedral scan between ' + mod_atom_sym1 + str(atom1) + ' - ' + mod_atom_sym2 + str(atom2) + ' - ' + mod_atom_sym3 + str(atom3) + ' - ' + mod_atom_sym4 + str(atom4))\r\n    print ('  ')\r\n\r\nelse:\r\n    print ('  ')\r\n    print ('Please provide a Gaussian .log file from a modredundant scan as input.')\r\n    print ('  ')\r\n  \r\n<\/code><\/pre>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This script uses a Gaussian .log file that corresponds to a scan. #!\/usr\/bin\/python from sys import argv import numpy as np import matplotlib.pyplot as plt periodic_table = {1:&rsquo;H&rsquo;, 2:&rsquo;He&rsquo;, 3:&rsquo;Li&rsquo;, 4:&rsquo;Be&rsquo;, 5:&rsquo;B&rsquo;, 6:&rsquo;C&rsquo;, 7:&rsquo;N&rsquo;, 8:&rsquo;O&rsquo;, 9:&rsquo;F&rsquo;, 10:&rsquo;Ne&rsquo;, 11:&rsquo;Na&rsquo;, 12:&rsquo;Mg&rsquo;, 13:&rsquo;Al&rsquo;, 14:&rsquo;Si&rsquo;, 15:&rsquo;P&rsquo;, 16:&rsquo;S&rsquo;, 17:&rsquo;Cl&rsquo;, 18:&rsquo;Ar&rsquo;, 19:&rsquo;K&rsquo;, 20:&rsquo;Ca&rsquo;, 21:&rsquo;Sc&rsquo;, 22:&rsquo;Ti&rsquo;, 23:&rsquo;V&rsquo;, 24:&rsquo;Cr&rsquo;, 25:&rsquo;Mn&rsquo;, 26:&rsquo;Fe&rsquo;, 27:&rsquo;Co&rsquo;, 28:&rsquo;Ni&rsquo;, [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"parent":2,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-363","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/perso.ens-lyon.fr\/carine.michel\/wp-json\/wp\/v2\/pages\/363","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/perso.ens-lyon.fr\/carine.michel\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/perso.ens-lyon.fr\/carine.michel\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/perso.ens-lyon.fr\/carine.michel\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/perso.ens-lyon.fr\/carine.michel\/wp-json\/wp\/v2\/comments?post=363"}],"version-history":[{"count":10,"href":"https:\/\/perso.ens-lyon.fr\/carine.michel\/wp-json\/wp\/v2\/pages\/363\/revisions"}],"predecessor-version":[{"id":399,"href":"https:\/\/perso.ens-lyon.fr\/carine.michel\/wp-json\/wp\/v2\/pages\/363\/revisions\/399"}],"up":[{"embeddable":true,"href":"https:\/\/perso.ens-lyon.fr\/carine.michel\/wp-json\/wp\/v2\/pages\/2"}],"wp:attachment":[{"href":"https:\/\/perso.ens-lyon.fr\/carine.michel\/wp-json\/wp\/v2\/media?parent=363"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}