新建
使用MPerformer进行分子感知/键极预测
Mn
推荐镜像 :mperformer:notebook
推荐机型 :c12_m92_1 * NVIDIA V100
赞
目录
数据集
XYZ(v1)
©️ Copyright 2023 @ Authors
作者:
王钒锰 📨
日期:2023-09-19
共享协议:本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。
快速开始:点击上方的 开始连接 按钮,选择 mperformer:notebook镜像 和GPU机型即可开始。
代码
文本
分子感知 (Molecular Perception)
代码
文本
分子感知的目的是基于仅知的部分分子信息(原子的3D坐标和原子类型)来预测出分子的其余结构特征(e.g., bond orders and formal charges),从而重建出完整的分子结构
换句话说,分子感知的目的就是要实现从分子xyz文件到sdf文件的转换
为此,我们设计开发了一个基于SE(3)-Transformer的通用分子感知框架:MPerformer, 可以基于原子的3D坐标和原子类型准确高效地预测出bond orders、formal charges等重要特征,从而重构出完整的分子结构。
开源代码:https://github.com/FanmengWang/MPerformer
快速体验:https://labs.dp.tech/projects/mperforemr/
代码
文本
准备数据
代码
文本
[1]
# 输入的xyz file的文件夹路径
inputs_path = '/bohr/0919-ttdm/v1/xyz_fold/'
# 处理后得到的sdf file的文件夹路径
outputs_path = '/outputs'
代码
文本
基本设置
代码
文本
[2]
import os
import time
import shutil
t1 = time.time()
data_path = '/MPerformer'
cache_path = '/MPerformer/cache'
weight_path = '/MPerformer/weight/checkpoint.pt'
task_name = '/MPerformer/cache'
result = '/MPerformer/cache/weight_test_cpu.out.pkl'
seed = 0
task_num = 3
conf_size = 1
only_polar = 0
batch_size = 32
dict_name = 'dict.txt'
loss_func = 'finetune_focal_loss_all_constraint_infer'
noH = True
add_noise = False
noise_weight = 0
noise_valid = 0
if os.path.exists(cache_path):
shutil.rmtree(cache_path)
os.mkdir(cache_path)
if os.path.exists(outputs_path):
shutil.rmtree(outputs_path)
os.mkdir(outputs_path)
代码
文本
处理输入的xyz文件,提取原子3D坐标和原子类型信息,并将其存入到lmdb中
代码
文本
[3]
import re
import lmdb
import numpy as np
import pickle
def numpy_seed(seed, *addl_seeds):
"""
Context manager which seeds the NumPy PRNG with the specified seed and
restores the state afterward
"""
if seed is None:
yield
return
if len(addl_seeds) > 0:
seed = int(hash((seed, *addl_seeds)) % 1e6)
state = np.random.get_state()
np.random.seed(seed)
try:
yield
finally:
np.random.set_state(state)
def read_xyz(filename_path, skipH=True):
"""
Read xyz data
:param filename: filename of .xyz file
:param skipH: Do not read H atoms
:return: atomtypes, coordinates and title section
"""
with open(filename_path,'r') as fin:
natoms = int(fin.readline())
title = fin.readline()[:-1]
q=0
qin = re.search("(?:CHARGE|CHG)=([-+]?\d*\.\d+|\d+|[-+]?\d)",title,re.IGNORECASE)
if qin:
q = float(qin.group(1))
coords = []
atomtypes = []
for x in range(natoms):
line = fin.readline().split()
if (line[0].lower()=='h') and skipH: continue
atomtypes.append(line[0])
coords.append([float(line[1]),float(line[2]),float(line[3])])
return(atomtypes, coords, q, title)
outputfilename = os.path.join(cache_path, 'test.lmdb')
env = lmdb.open(
outputfilename,
subdir=False,
readonly=False,
lock=False,
readahead=False,
meminit=False,
max_readers=1,
map_size=int(1000e9),
)
txn_writer = env.begin(write=True)
numpy_seed(seed)
xyz_num = 0
for filename in os.listdir(inputs_path):
if not filename.endswith('.xyz'):
continue
filename_path = os.path.join(inputs_path, filename)
atomtypes, coords, q, title = read_xyz(filename_path, skipH=noH)
coords = np.array(coords, dtype=np.float32)
inner_output = {}
inner_output['data'] = filename.split('.')[0]
inner_output['atoms'] = atomtypes
inner_output['coordinates'] = [coords]
inner_output['target'] = np.array([2] * len(atomtypes), dtype=np.float32)
inner_output['atom_H_num'] = np.array([2] * len(atomtypes), dtype=np.float32)
bond = np.array(list(np.zeros((len(atomtypes),len(atomtypes)), dtype=int)))
for i in range(len(atomtypes)):
bond[i][i] = -1
inner_output['bond'] = bond
txn_writer.put(f"{inner_output['data']}".encode("ascii"), pickle.dumps(inner_output, protocol=-1))
xyz_num = xyz_num + 1
txn_writer.commit()
env.close()
print(f'The number of xyz file is {xyz_num}')
The number of xyz file is 800
代码
文本
调用MPerformer预测bond orders、formal charges等重要特征
代码
文本
[4]
cmd = "python /MPerformer/MPerformer/infer.py --user-dir {} {} --task-name {} --valid-subset test --results-path {} --noise-valid {} --num-workers 1 --ddp-backend=c10d --batch-size {} --task MPerformer --loss {} --arch MPerformer_base --classification-head-name {} --num-classes {} --dict-name {} --conf-size {} --only-polar {} --path {} --fp16 --fp16-init-scale 4 --fp16-scale-window 256 --log-interval 50 --log-format simple".format(os.path.join(data_path, 'MPerformer'), data_path, task_name, cache_path, noise_valid, batch_size, loss_func, task_name, task_num, dict_name, conf_size, only_polar, weight_path)
os.system(cmd)
0
代码
文本
基于预测结果重构出完整的分子结构
代码
文本
[5]
import pandas as pd
from tqdm import tqdm, trange
from multiprocessing import Pool
import dpdata
def create_sdfile(name, atomtypes, coords, row1, row2, bond, charge):
"""
Creates string with SD info
:param name: molecule name
:param atomtypes: atomic types
:param coords: coordinates
:return: molblock
"""
ins = name + "\n"
# comment block
ins += "MPerformer generated sdf\n"
ins += "\n"
ins += "%3d%3d 0 0 0 0 0 0 0 0 1 V2000\n" % (len(atomtypes), len(row1))
# atomb block
for at, xyz in zip(atomtypes, coords):
ins += "%10.4f%10.4f%10.4f %-2s 0 0 0 0 0\n" % (xyz[0], xyz[1], xyz[2], at)
# ins += "%2s %12.4f %12.4f %12.4f \n" % ( at,xyz[0], xyz[1], xyz[2])
# bond block
for index in range(len(row1)):
ins += "%3d%3d%3d 0 0 0 0\n" % (row1[index], row2[index], bond[index])
add_charge_num = 0
charge_ins = ""
for idx, charge_num in enumerate(charge):
if charge_num != 0:
charge_ins += f" {idx+1} {charge_num}"
add_charge_num = add_charge_num + 1
if add_charge_num != 0:
charge_ins = f"M CHG {add_charge_num}" + charge_ins
ins += charge_ins
ins += "\n"
print(charge_ins)
ins += "M END"
return(ins)
def check_consist_valid(mol_file):
mol_file= mol_file
pred_atom_charge = mol_file["pred_atom_charge"].view(-1)
target = mol_file["target"]
masked_tokens0 = target.ne(padding_idx)
sample_size0 = masked_tokens0.long().sum()
pred_atom_charge0 = pred_atom_charge[masked_tokens0]
charge_list = []
for i in range(pred_atom_charge0.shape[0]):
if pred_atom_charge0[i] < -0.5:
charge_list.append(-1)
continue
if pred_atom_charge0[i] > 0.5:
charge_list.append(1)
continue
charge_list.append(0)
pred_atom_H = mol_file["pred_atom_H"].view(-1)
atom_H_target = mol_file["atom_H_target"]
masked_atom_H_tokens = atom_H_target.ne(atom_H_pad_idx)
pred_atom_H0 = pred_atom_H[masked_atom_H_tokens]
H_list = []
for i in range(pred_atom_H0.shape[0]):
if pred_atom_H0[i] > 2.5:
H_list.append(3)
continue
if pred_atom_H0[i] < 0.5:
H_list.append(0)
continue
if pred_atom_H0[i] < 1.5:
H_list.append(1)
continue
H_list.append(2)
pred_atom_bond = mol_file["pred_atom_bond"][:, :, 0]
bond_masked_tokens = masked_tokens0
masked_pred_atom_bond = pred_atom_bond[bond_masked_tokens]
masked_bond_target = mol_file['bond_target'][bond_masked_tokens]
non_pad_pos = (masked_bond_target >= 0) & (masked_bond_target != bond_pad_idx)
masked_bond_target = masked_bond_target[non_pad_pos]
masked_pred_atom_bond = masked_pred_atom_bond[non_pad_pos]
bond_list = []
for i in range(masked_pred_atom_bond.shape[0]):
if masked_pred_atom_bond[i] < 0.5:
bond_list.append(0)
continue
if masked_pred_atom_bond[i] > 2.5:
bond_list.append(3)
continue
if masked_pred_atom_bond[i] < 1.25:
bond_list.append(1)
continue
if masked_pred_atom_bond[i] > 1.75:
bond_list.append(2)
continue
bond_list.append(4)
row1 = []
row2 = []
bond_type = []
index = 0
for i in range(sample_size0):
for j in range(sample_size0):
if j == i:
continue
if bond_list[index] != 0 and i < j:
row1.append(i + 1)
row2.append(j + 1)
bond_type.append(bond_list[index])
index = index + 1
ins = create_sdfile(mol_file['id_name'], mol_file['atoms'], mol_file['coords'], row1, row2, bond_type, charge_list)
filename = os.path.join(outputs_path, mol_file['id_name'] + '.sdf')
xyz_filename = os.path.join(inputs_path, mol_file['id_name'] + '.xyz')
with open(filename, 'w') as f:
f.write(ins)
try:
suppl = Chem.SDMolSupplier(filename)
mol = [mol for mol in suppl if mol][0]
except:
try:
suppl = Chem.SDMolSupplier(filename, sanitize=False)
mol = [mol for mol in suppl if mol][0]
system = dpdata.BondOrderSystem(rdkit_mol=mol)
Chem.Kekulize(mol)
except:
return None
with Chem.SDWriter(filename) as w:
w.write(mol)
padding_idx = 0
bond_pad_idx = 6
atom_H_pad_idx = 6
env = lmdb.open(
outputfilename,
subdir=False,
readonly=True,
lock=False,
readahead=True,
meminit=False,
max_readers=8,
map_size=int(1000e9),
)
txn = env.begin()
predicts = pd.read_pickle(result)
mol_file_list = []
for epoch in range(len(predicts)):
predict = predicts[epoch]
bsz = predicts[epoch]['bsz']
for index in range(bsz):
mol_file = {}
mol_file['id_name'] = predict['id_name'][index]
value = pickle.loads(txn.get(mol_file['id_name'].encode()))
mol_file['atoms'] = list(np.array(value['atoms']))
mol_file['coords'] = list(np.array(value['coordinates'][0]))
mol_file['logit_output'] = predict['logit_output'][index].float()
mol_file['logit_output'] = predict['logit_output'][index].float()
mol_file['target'] = predict['target'][index]
mol_file['logit_atom_H_output'] = predict['logit_atom_H_output'][index].float()
mol_file['atom_H_target'] = predict['atom_H_target'][index]
mol_file['logit_bond_output'] = predict['logit_bond_output'][index].float()
mol_file['bond_target'] = predict['bond_target'][index]
mol_file['pred_atom_charge'] = predict['pred_atom_charge'][index].float()
mol_file['pred_atom_H'] = predict['pred_atom_H'][index].float()
mol_file['pred_atom_bond'] = predict['pred_atom_bond'][index].float()
mol_file_list.append(mol_file)
with Pool() as pool:
for inner_output in tqdm(pool.imap(check_consist_valid, mol_file_list), total=len(mol_file_list)):
pass
/opt/conda/lib/python3.8/site-packages/tqdm/auto.py:22: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html from .autonotebook import tqdm as notebook_tqdm 0%| | 0/800 [00:00<?, ?it/s] 0%| | 1/800 [00:00<01:37, 8.18it/s] 3%|▎ | 25/800 [00:00<00:06, 123.82it/s] 6%|▌ | 49/800 [00:00<00:04, 155.92it/s] 9%|▉ | 73/800 [00:00<00:04, 167.40it/s] 12%|█▏ | 96/800 [00:00<00:03, 181.70it/s] 15%|█▌ | 120/800 [00:00<00:03, 179.53it/s] 18%|█▊ | 148/800 [00:00<00:03, 204.38it/s] 21%|██▏ | 170/800 [00:00<00:03, 202.56it/s] 24%|██▍ | 194/800 [00:01<00:02, 209.31it/s] 27%|██▋ | 218/800 [00:01<00:02, 197.92it/s] 31%|███ | 247/800 [00:01<00:02, 221.47it/s] 34%|███▍ | 270/800 [00:01<00:02, 220.85it/s] 37%|███▋ | 293/800 [00:01<00:02, 214.90it/s] 40%|███▉ | 318/800 [00:01<00:02, 222.29it/s] 43%|████▎ | 343/800 [00:01<00:02, 224.77it/s] 46%|████▋ | 370/800 [00:01<00:01, 218.08it/s] 49%|████▉ | 393/800 [00:01<00:01, 212.62it/s] 52%|█████▏ | 418/800 [00:02<00:01, 214.92it/s] 55%|█████▌ | 441/800 [00:02<00:01, 205.78it/s] 58%|█████▊ | 464/800 [00:02<00:01, 207.41it/s] 61%|██████ | 488/800 [00:02<00:01, 193.75it/s] 64%|██████▍ | 510/800 [00:02<00:01, 196.76it/s] 67%|██████▋ | 534/800 [00:02<00:01, 205.26it/s] 70%|██████▉ | 557/800 [00:02<00:01, 200.57it/s] 72%|███████▏ | 579/800 [00:02<00:01, 189.88it/s] 76%|███████▌ | 605/800 [00:03<00:00, 199.76it/s] 78%|███████▊ | 628/800 [00:03<00:00, 206.08it/s] 82%|████████▏ | 653/800 [00:03<00:00, 217.29it/s] 84%|████████▍ | 675/800 [00:03<00:00, 214.67it/s] 87%|████████▋ | 697/800 [00:03<00:00, 207.36it/s] 90%|████████▉ | 718/800 [00:03<00:00, 197.86it/s] 92%|█████████▎| 740/800 [00:03<00:00, 196.28it/s] 95%|█████████▌| 761/800 [00:03<00:00, 189.41it/s] 100%|██████████| 800/800 [00:03<00:00, 203.71it/s]
代码
文本
统计结果
代码
文本
[6]
t2 = time.time()
data_process_time = t2 - t1
print(os.listdir(outputs_path))
print(f'input_xyz_fold: {filename}')
print(f'output_sdf_fold: {outputs_path}')
print(f'used_time: {data_process_time / 60} min')
['437.sdf', '176.sdf', '347.sdf', '433.sdf', '340.sdf', '662.sdf', '719.sdf', '462.sdf', '109.sdf', '84.sdf', '484.sdf', '745.sdf', '515.sdf', '156.sdf', '6.sdf', '578.sdf', '80.sdf', '246.sdf', '353.sdf', '291.sdf', '653.sdf', '2.sdf', '42.sdf', '317.sdf', '331.sdf', '632.sdf', '231.sdf', '266.sdf', '714.sdf', '428.sdf', '549.sdf', '607.sdf', '568.sdf', '740.sdf', '680.sdf', '418.sdf', '446.sdf', '4.sdf', '531.sdf', '48.sdf', '518.sdf', '32.sdf', '206.sdf', '706.sdf', '521.sdf', '792.sdf', '290.sdf', '670.sdf', '40.sdf', '16.sdf', '663.sdf', '486.sdf', '767.sdf', '699.sdf', '777.sdf', '287.sdf', '411.sdf', '289.sdf', '51.sdf', '119.sdf', '30.sdf', '161.sdf', '658.sdf', '665.sdf', '196.sdf', '19.sdf', '420.sdf', '467.sdf', '754.sdf', '208.sdf', '163.sdf', '483.sdf', '154.sdf', '496.sdf', '572.sdf', '625.sdf', '36.sdf', '678.sdf', '627.sdf', '123.sdf', '455.sdf', '323.sdf', '452.sdf', '554.sdf', '440.sdf', '648.sdf', '593.sdf', '24.sdf', '14.sdf', '383.sdf', '576.sdf', '292.sdf', '268.sdf', '530.sdf', '10.sdf', '0.sdf', '219.sdf', '454.sdf', '197.sdf', '730.sdf', '527.sdf', '365.sdf', '200.sdf', '120.sdf', '668.sdf', '68.sdf', '514.sdf', '186.sdf', '765.sdf', '776.sdf', '22.sdf', '729.sdf', '5.sdf', '443.sdf', '8.sdf', '377.sdf', '217.sdf', '368.sdf', '720.sdf', '757.sdf', '300.sdf', '256.sdf', '46.sdf', '50.sdf', '336.sdf', '180.sdf', '43.sdf', '305.sdf', '798.sdf', '536.sdf', '778.sdf', '613.sdf', '547.sdf', '87.sdf', '143.sdf', '38.sdf', '233.sdf', '468.sdf', '89.sdf', '711.sdf', '1.sdf', '480.sdf', '773.sdf', '477.sdf', '129.sdf', '451.sdf', '524.sdf', '286.sdf', '421.sdf', '402.sdf', '415.sdf', '229.sdf', '29.sdf', '770.sdf', '115.sdf', '78.sdf', '580.sdf', '332.sdf', '326.sdf', '60.sdf', '552.sdf', '671.sdf', '712.sdf', '182.sdf', '476.sdf', '696.sdf', '288.sdf', '753.sdf', '75.sdf', '155.sdf', '96.sdf', '360.sdf', '638.sdf', '114.sdf', '616.sdf', '350.sdf', '211.sdf', '529.sdf', '414.sdf', '623.sdf', '273.sdf', '498.sdf', '460.sdf', '439.sdf', '172.sdf', '278.sdf', '373.sdf', '131.sdf', '263.sdf', '406.sdf', '689.sdf', '94.sdf', '91.sdf', '214.sdf', '566.sdf', '502.sdf', '592.sdf', '634.sdf', '425.sdf', '339.sdf', '582.sdf', '795.sdf', '384.sdf', '142.sdf', '76.sdf', '100.sdf', '691.sdf', '657.sdf', '444.sdf', '367.sdf', '490.sdf', '732.sdf', '53.sdf', '784.sdf', '203.sdf', '610.sdf', '703.sdf', '378.sdf', '351.sdf', '645.sdf', '74.sdf', '688.sdf', '585.sdf', '750.sdf', '705.sdf', '262.sdf', '789.sdf', '205.sdf', '771.sdf', '167.sdf', '335.sdf', '125.sdf', '427.sdf', '346.sdf', '434.sdf', '73.sdf', '436.sdf', '160.sdf', '128.sdf', '615.sdf', '64.sdf', '708.sdf', '709.sdf', '701.sdf', '629.sdf', '302.sdf', '599.sdf', '617.sdf', '666.sdf', '191.sdf', '27.sdf', '330.sdf', '319.sdf', '293.sdf', '338.sdf', '86.sdf', '388.sdf', '59.sdf', '759.sdf', '643.sdf', '228.sdf', '322.sdf', '717.sdf', '517.sdf', '526.sdf', '394.sdf', '251.sdf', '153.sdf', '158.sdf', '258.sdf', '164.sdf', '679.sdf', '295.sdf', '207.sdf', '199.sdf', '240.sdf', '370.sdf', '503.sdf', '746.sdf', '525.sdf', '141.sdf', '344.sdf', '399.sdf', '280.sdf', '532.sdf', '69.sdf', '630.sdf', '220.sdf', '677.sdf', '587.sdf', '700.sdf', '500.sdf', '565.sdf', '724.sdf', '23.sdf', '21.sdf', '639.sdf', '499.sdf', '533.sdf', '445.sdf', '194.sdf', '401.sdf', '170.sdf', '575.sdf', '449.sdf', '550.sdf', '337.sdf', '598.sdf', '661.sdf', '95.sdf', '431.sdf', '413.sdf', '382.sdf', '97.sdf', '509.sdf', '138.sdf', '345.sdf', '124.sdf', '387.sdf', '13.sdf', '748.sdf', '304.sdf', '398.sdf', '118.sdf', '725.sdf', '758.sdf', '333.sdf', '430.sdf', '309.sdf', '586.sdf', '67.sdf', '31.sdf', '407.sdf', '122.sdf', '747.sdf', '495.sdf', '134.sdf', '794.sdf', '756.sdf', '324.sdf', '390.sdf', '216.sdf', '92.sdf', '553.sdf', '640.sdf', '559.sdf', '571.sdf', '126.sdf', '136.sdf', '684.sdf', '570.sdf', '621.sdf', '133.sdf', '202.sdf', '458.sdf', '151.sdf', '465.sdf', '769.sdf', '655.sdf', '650.sdf', '349.sdf', '716.sdf', '422.sdf', '651.sdf', '470.sdf', '741.sdf', '744.sdf', '132.sdf', '667.sdf', '277.sdf', '159.sdf', '237.sdf', '357.sdf', '395.sdf', '386.sdf', '321.sdf', '783.sdf', '355.sdf', '230.sdf', '225.sdf', '41.sdf', '672.sdf', '62.sdf', '110.sdf', '453.sdf', '310.sdf', '755.sdf', '261.sdf', '513.sdf', '797.sdf', '82.sdf', '70.sdf', '276.sdf', '713.sdf', '168.sdf', '799.sdf', '285.sdf', '56.sdf', '631.sdf', '376.sdf', '601.sdf', '224.sdf', '252.sdf', '727.sdf', '728.sdf', '618.sdf', '113.sdf', '739.sdf', '102.sdf', '190.sdf', '269.sdf', '173.sdf', '259.sdf', '54.sdf', '535.sdf', '560.sdf', '556.sdf', '461.sdf', '391.sdf', '588.sdf', '569.sdf', '417.sdf', '264.sdf', '764.sdf', '375.sdf', '247.sdf', '265.sdf', '218.sdf', '303.sdf', '624.sdf', '563.sdf', '537.sdf', '171.sdf', '209.sdf', '55.sdf', '239.sdf', '169.sdf', '779.sdf', '673.sdf', '489.sdf', '410.sdf', '329.sdf', '793.sdf', '204.sdf', '736.sdf', '248.sdf', '772.sdf', '683.sdf', '676.sdf', '242.sdf', '215.sdf', '419.sdf', '656.sdf', '358.sdf', '223.sdf', '762.sdf', '166.sdf', '675.sdf', '561.sdf', '7.sdf', '600.sdf', '511.sdf', '790.sdf', '174.sdf', '695.sdf', '307.sdf', '140.sdf', '210.sdf', '584.sdf', '494.sdf', '456.sdf', '35.sdf', '58.sdf', '316.sdf', '397.sdf', '145.sdf', '694.sdf', '116.sdf', '198.sdf', '396.sdf', '707.sdf', '579.sdf', '481.sdf', '282.sdf', '474.sdf', '702.sdf', '654.sdf', '697.sdf', '761.sdf', '52.sdf', '488.sdf', '633.sdf', '135.sdf', '408.sdf', '9.sdf', '296.sdf', '611.sdf', '478.sdf', '88.sdf', '594.sdf', '491.sdf', '426.sdf', '614.sdf', '179.sdf', '644.sdf', '226.sdf', '181.sdf', '775.sdf', '137.sdf', '544.sdf', '362.sdf', '112.sdf', '342.sdf', '320.sdf', '548.sdf', '244.sdf', '733.sdf', '379.sdf', '162.sdf', '558.sdf', '101.sdf', '107.sdf', '760.sdf', '270.sdf', '212.sdf', '464.sdf', '274.sdf', '34.sdf', '619.sdf', '341.sdf', '604.sdf', '583.sdf', '685.sdf', '298.sdf', '501.sdf', '641.sdf', '591.sdf', '33.sdf', '234.sdf', '581.sdf', '121.sdf', '652.sdf', '348.sdf', '787.sdf', '567.sdf', '249.sdf', '65.sdf', '272.sdf', '577.sdf', '519.sdf', '366.sdf', '766.sdf', '18.sdf', '482.sdf', '442.sdf', '99.sdf', '400.sdf', '106.sdf', '504.sdf', '236.sdf', '361.sdf', '435.sdf', '416.sdf', '385.sdf', '432.sdf', '403.sdf', '734.sdf', '622.sdf', '165.sdf', '45.sdf', '57.sdf', '77.sdf', '742.sdf', '81.sdf', '479.sdf', '774.sdf', '520.sdf', '506.sdf', '473.sdf', '674.sdf', '192.sdf', '751.sdf', '235.sdf', '325.sdf', '609.sdf', '698.sdf', '538.sdf', '573.sdf', '780.sdf', '603.sdf', '510.sdf', '681.sdf', '508.sdf', '315.sdf', '83.sdf', '15.sdf', '497.sdf', '93.sdf', '313.sdf', '649.sdf', '37.sdf', '380.sdf', '686.sdf', '551.sdf', '294.sdf', '731.sdf', '354.sdf', '44.sdf', '308.sdf', '441.sdf', '597.sdf', '522.sdf', '117.sdf', '245.sdf', '605.sdf', '146.sdf', '493.sdf', '105.sdf', '636.sdf', '193.sdf', '404.sdf', '715.sdf', '343.sdf', '786.sdf', '540.sdf', '647.sdf', '184.sdf', '104.sdf', '311.sdf', '412.sdf', '507.sdf', '738.sdf', '271.sdf', '188.sdf', '381.sdf', '327.sdf', '749.sdf', '472.sdf', '108.sdf', '424.sdf', '328.sdf', '405.sdf', '111.sdf', '457.sdf', '602.sdf', '608.sdf', '241.sdf', '438.sdf', '423.sdf', '626.sdf', '356.sdf', '352.sdf', '178.sdf', '555.sdf', '546.sdf', '130.sdf', '692.sdf', '152.sdf', '542.sdf', '718.sdf', '781.sdf', '541.sdf', '150.sdf', '318.sdf', '63.sdf', '743.sdf', '312.sdf', '185.sdf', '752.sdf', '791.sdf', '183.sdf', '606.sdf', '393.sdf', '195.sdf', '250.sdf', '528.sdf', '177.sdf', '299.sdf', '253.sdf', '175.sdf', '788.sdf', '213.sdf', '763.sdf', '283.sdf', '710.sdf', '127.sdf', '469.sdf', '721.sdf', '471.sdf', '28.sdf', '660.sdf', '723.sdf', '459.sdf', '664.sdf', '284.sdf', '475.sdf', '26.sdf', '371.sdf', '737.sdf', '334.sdf', '275.sdf', '642.sdf', '61.sdf', '221.sdf', '628.sdf', '735.sdf', '369.sdf', '690.sdf', '254.sdf', '782.sdf', '72.sdf', '25.sdf', '47.sdf', '590.sdf', '545.sdf', '90.sdf', '485.sdf', '392.sdf', '543.sdf', '448.sdf', '574.sdf', '187.sdf', '492.sdf', '450.sdf', '363.sdf', '785.sdf', '157.sdf', '612.sdf', '279.sdf', '523.sdf', '534.sdf', '71.sdf', '463.sdf', '596.sdf', '139.sdf', '516.sdf', '297.sdf', '11.sdf', '557.sdf', '359.sdf', '227.sdf', '409.sdf', '620.sdf', '374.sdf', '314.sdf', '260.sdf', '85.sdf', '389.sdf', '103.sdf', '267.sdf', '147.sdf', '539.sdf', '3.sdf', '659.sdf', '637.sdf', '98.sdf', '687.sdf', '39.sdf', '20.sdf', '768.sdf', '281.sdf', '693.sdf', '589.sdf', '306.sdf', '222.sdf', '144.sdf', '487.sdf', '796.sdf', '243.sdf', '429.sdf', '704.sdf', '189.sdf', '466.sdf', '682.sdf', '149.sdf', '201.sdf', '238.sdf', '49.sdf', '564.sdf', '726.sdf', '635.sdf', '372.sdf', '595.sdf', '722.sdf', '512.sdf', '257.sdf', '148.sdf', '669.sdf', '447.sdf', '646.sdf', '255.sdf', '232.sdf', '301.sdf', '17.sdf', '66.sdf', '12.sdf', '364.sdf', '505.sdf', '562.sdf', '79.sdf'] input_xyz_fold: 99.xyz output_sdf_fold: /outputs used_time: 0.708737599849701 min
代码
文本
点个赞吧
推荐阅读
公开
基于Transformer对Polymer性质进行预测Mn
发布于 2023-11-07
2 赞1 转存文件
公开
Re: 从零开始的电子结构生活(一)HF 近似、STO-3G 基组和 SCF 计算Weiliang Luo
更新于 2024-09-10
14 赞6 转存文件