Compare commits
2 Commits
c2fd6857cc
...
70e46124a0
Author | SHA1 | Date | |
---|---|---|---|
70e46124a0 | |||
e70435e807 |
43
cord/main.py
43
cord/main.py
@ -124,8 +124,10 @@ def on_save():
|
|||||||
@st.cache_resource
|
@st.cache_resource
|
||||||
def load_data(file):
|
def load_data(file):
|
||||||
# 读取数据文件
|
# 读取数据文件
|
||||||
if file is not None:
|
|
||||||
try:
|
try:
|
||||||
|
if st.session_state.get("use_example", False):
|
||||||
|
data = create_example()[0]
|
||||||
|
else:
|
||||||
data = pd.read_excel(file) if file.name.endswith((".xlsx", ".xls")) else pd.read_csv(file)
|
data = pd.read_excel(file) if file.name.endswith((".xlsx", ".xls")) else pd.read_csv(file)
|
||||||
if data.columns.tolist() != ["Name", "Energy"]:
|
if data.columns.tolist() != ["Name", "Energy"]:
|
||||||
st.warning("Format should be Name, Energy. Modified automatically.")
|
st.warning("Format should be Name, Energy. Modified automatically.")
|
||||||
@ -133,8 +135,6 @@ def load_data(file):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
st.error(f"Error reading file: {e}")
|
st.error(f"Error reading file: {e}")
|
||||||
exit()
|
exit()
|
||||||
else:
|
|
||||||
exit()
|
|
||||||
|
|
||||||
INFLU_FACTORS = [0.5] * data.shape[0] * 2 # 动态创建数组
|
INFLU_FACTORS = [0.5] * data.shape[0] * 2 # 动态创建数组
|
||||||
|
|
||||||
@ -147,34 +147,52 @@ def load_data(file):
|
|||||||
|
|
||||||
return data, INFLU_FACTORS,K_POS
|
return data, INFLU_FACTORS,K_POS
|
||||||
|
|
||||||
|
@st.cache_data
|
||||||
|
def create_example():
|
||||||
|
tmp_file = io.BytesIO()
|
||||||
|
example = pd.DataFrame({"Name":["reactant","TS","result"], "Energy":[-400.310327,-400.210017,-400.341576,]})
|
||||||
|
example.to_excel(tmp_file, index=False)
|
||||||
|
return example,tmp_file
|
||||||
|
|
||||||
|
|
||||||
out_file = io.BytesIO()
|
out_file = io.BytesIO()
|
||||||
|
|
||||||
st.set_page_config(
|
st.set_page_config(
|
||||||
page_title="反应坐标绘制",
|
page_title="反应坐标绘制",
|
||||||
page_icon=":chart_with_upwards_trend:",
|
page_icon=":chart_with_upwards_trend:",
|
||||||
initial_sidebar_state="expanded"
|
initial_sidebar_state="expanded",layout="wide"
|
||||||
)
|
)
|
||||||
st.title("反应坐标绘制")
|
st.title("反应坐标绘制")
|
||||||
st.write("---")
|
st.write("---")
|
||||||
|
|
||||||
file = st.file_uploader("上传能量文件", type=["xlsx", "xls", "csv"],key="file")
|
file = st.file_uploader("上传能量文件", type=["xlsx", "xls", "csv"],key="file")
|
||||||
if not file:
|
|
||||||
st.set_page_config(layout="centered")
|
if not file and not st.session_state.get("use_example", False) and "datas" not in st.session_state:
|
||||||
|
# st.set_page_config(layout="centered")
|
||||||
st.write("按照下列格式上传表格。请保证列名和范例一致,或直接下载。")
|
st.write("按照下列格式上传表格。请保证列名和范例一致,或直接下载。")
|
||||||
st.warning("注意,Energy单位为Hatree,程序将自动转换为kcal/mol的相对能量")
|
st.warning("注意,Energy单位为Hatree,程序将自动转换为kcal/mol的相对能量")
|
||||||
example = pd.DataFrame({"Name":["reactant","TS","result"], "Energy":[-400.310327,-400.210017,-400.341576,]})
|
example,tmp_file = create_example()
|
||||||
st.dataframe(example,hide_index=True)
|
st.dataframe(example,hide_index=True)
|
||||||
tmp_file = io.BytesIO()
|
|
||||||
example.to_excel(tmp_file, index=False)
|
|
||||||
st.download_button("下载模板",data=tmp_file,file_name="reaction_coordinate_example.xlsx")
|
st.download_button("下载模板",data=tmp_file,file_name="reaction_coordinate_example.xlsx")
|
||||||
|
def use_tmp():
|
||||||
|
global file
|
||||||
|
st.session_state["use_example"] = True
|
||||||
|
file = tmp_file
|
||||||
|
st.button("使用样例使用",on_click=use_tmp)
|
||||||
st.stop()
|
st.stop()
|
||||||
else:
|
else:
|
||||||
st.set_page_config(layout="wide")
|
pass
|
||||||
|
# st.set_page_config(layout="wide")
|
||||||
col1,col2 = st.columns([0.4,0.6],gap="medium")
|
col1,col2 = st.columns([0.4,0.6],gap="medium")
|
||||||
|
|
||||||
|
|
||||||
with col2:
|
with col2:
|
||||||
|
|
||||||
|
if "datas" not in st.session_state:
|
||||||
data, INFLU_FACTORS,K_POS = load_data(file)
|
data, INFLU_FACTORS,K_POS = load_data(file)
|
||||||
|
st.session_state["datas"] = (data, INFLU_FACTORS,K_POS)
|
||||||
|
else:
|
||||||
|
data, INFLU_FACTORS, K_POS = st.session_state["datas"]
|
||||||
|
|
||||||
fig,lines = plot_reaction_coordinate()
|
fig,lines = plot_reaction_coordinate()
|
||||||
stfig = st.pyplot(fig,False)
|
stfig = st.pyplot(fig,False)
|
||||||
@ -211,7 +229,6 @@ with col1:
|
|||||||
xmin,xmax = plt.xlim()
|
xmin,xmax = plt.xlim()
|
||||||
ymin,ymax = plt.ylim()
|
ymin,ymax = plt.ylim()
|
||||||
st.session_state["xylim"] = (xmin,xmax,ymin,ymax)
|
st.session_state["xylim"] = (xmin,xmax,ymin,ymax)
|
||||||
st.info(st.session_state["xylim"])
|
|
||||||
|
|
||||||
xmin,xmax,ymin,ymax = st.session_state["xylim"]
|
xmin,xmax,ymin,ymax = st.session_state["xylim"]
|
||||||
dxmin,dxmax,dymin,dymax = abs(xmin)*0.5,abs(xmax)*0.5,abs(ymin)*0.5,abs(ymax)*0.5
|
dxmin,dxmax,dymin,dymax = abs(xmin)*0.5,abs(xmax)*0.5,abs(ymin)*0.5,abs(ymax)*0.5
|
||||||
@ -234,7 +251,9 @@ with col1:
|
|||||||
|
|
||||||
st.slider("字体大小",8,20, value=12, key="font_size",
|
st.slider("字体大小",8,20, value=12, key="font_size",
|
||||||
on_change=lambda: plt.rcParams.update({'font.size': st.session_state.get("font_size", 12)}))
|
on_change=lambda: plt.rcParams.update({'font.size': st.session_state.get("font_size", 12)}))
|
||||||
|
if st.button("重置",type="primary"):
|
||||||
|
st.session_state.clear()
|
||||||
|
st.rerun()
|
||||||
|
|
||||||
st.write("---")
|
st.write("---")
|
||||||
st.dataframe(data)
|
st.dataframe(data)
|
||||||
|
@ -93,7 +93,7 @@ def get_pubchem_properties(cid:str) -> Dict[str, Optional[List[str]]]:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def search_compound(query: str, search_type: str = "name"):
|
def search_compound(query: str, search_type: str = "name",use_word = False):
|
||||||
"""
|
"""
|
||||||
根据不同类型搜索化合物
|
根据不同类型搜索化合物
|
||||||
|
|
||||||
@ -106,7 +106,11 @@ def search_compound(query: str, search_type: str = "name"):
|
|||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
if search_type == "name":
|
if search_type == "name":
|
||||||
|
if use_word:
|
||||||
|
compounds = pcp.get_compounds(query, 'name',name_type="word")
|
||||||
|
else:
|
||||||
compounds = pcp.get_compounds(query, 'name')
|
compounds = pcp.get_compounds(query, 'name')
|
||||||
|
|
||||||
elif search_type == "formula":
|
elif search_type == "formula":
|
||||||
compounds = pcp.get_compounds(query, 'formula')
|
compounds = pcp.get_compounds(query, 'formula')
|
||||||
elif search_type == "smiles":
|
elif search_type == "smiles":
|
||||||
@ -236,22 +240,6 @@ def reaction_table_page():
|
|||||||
|
|
||||||
''')
|
''')
|
||||||
|
|
||||||
# 初始化数据
|
|
||||||
if 'reaction_data' not in st.session_state:
|
|
||||||
df = pd.DataFrame([[None,None,None,None,None,None,None,None]],columns=[
|
|
||||||
"物质",
|
|
||||||
"分子量",
|
|
||||||
"当量",
|
|
||||||
"用量(mmol)",
|
|
||||||
"质量(g)",
|
|
||||||
"密度(g/mL)",
|
|
||||||
"体积(mL)",
|
|
||||||
"备注"
|
|
||||||
],dtype="float")
|
|
||||||
df["物质"] = df["物质"].astype("string")
|
|
||||||
df["备注"] = df["备注"].astype("string")
|
|
||||||
st.session_state.reaction_data = df
|
|
||||||
|
|
||||||
|
|
||||||
st.info(f"💡 当量为0时,该物质不参与当量计算。")
|
st.info(f"💡 当量为0时,该物质不参与当量计算。")
|
||||||
use_on_change = st.checkbox("立即计算", value=True)
|
use_on_change = st.checkbox("立即计算", value=True)
|
||||||
@ -654,6 +642,12 @@ def compound_search_page():
|
|||||||
f"输入{mp[search_type]}",
|
f"输入{mp[search_type]}",
|
||||||
placeholder="例如: ethanol, C2H6O, CCO"
|
placeholder="例如: ethanol, C2H6O, CCO"
|
||||||
)
|
)
|
||||||
|
if search_type == "name" and query and not re.match(r"[a-zA-Z\d\-,\.]+",query):
|
||||||
|
use_tanslate = st.checkbox("使用翻译",True)
|
||||||
|
else:
|
||||||
|
use_tanslate = False
|
||||||
|
use_word = st.checkbox("使用关键词(仅当无法直接搜到时勾选,可能会找错化合物)")
|
||||||
|
|
||||||
|
|
||||||
search_button = st.button("🔍 搜索", type="primary")
|
search_button = st.button("🔍 搜索", type="primary")
|
||||||
|
|
||||||
@ -667,7 +661,31 @@ def compound_search_page():
|
|||||||
st.error(f"计算分子量时出错: {e}")
|
st.error(f"计算分子量时出错: {e}")
|
||||||
else:
|
else:
|
||||||
with st.spinner("正在搜索..."):
|
with st.spinner("正在搜索..."):
|
||||||
_compound = search_compound(query, search_type)
|
_compound = None
|
||||||
|
if use_tanslate:
|
||||||
|
try:
|
||||||
|
req1 = requests.get(f"https://api.52vmy.cn/api/query/fanyi?msg={query}")
|
||||||
|
req1.raise_for_status()
|
||||||
|
trans = req1.json()["data"]["target"]
|
||||||
|
_compound = search_compound(trans, search_type,use_word)
|
||||||
|
except Exception as e:
|
||||||
|
st.error("第一个翻译引擎发生错误")
|
||||||
|
traceback.print_exc()
|
||||||
|
if _compound is None:
|
||||||
|
st.error("第一个翻译引擎失败")
|
||||||
|
try:
|
||||||
|
req1 = requests.get(f"https://v.api.aa1.cn/api/api-fanyi-yd/index.php?msg={query}&type=1")
|
||||||
|
req1.raise_for_status()
|
||||||
|
trans = req1.json()["text"]
|
||||||
|
_compound = search_compound(trans, search_type,use_word)
|
||||||
|
except Exception as e:
|
||||||
|
st.error("第二个翻译引擎发生错误")
|
||||||
|
traceback.print_exc()
|
||||||
|
if _compound is None:
|
||||||
|
st.error("所有翻译都失败了。")
|
||||||
|
|
||||||
|
if _compound is None:
|
||||||
|
_compound = search_compound(query, search_type,use_word)
|
||||||
|
|
||||||
print(_compound,search_type)
|
print(_compound,search_type)
|
||||||
|
|
||||||
@ -863,6 +881,22 @@ def compound_search_page():
|
|||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
# initialize reaction data
|
||||||
|
if 'reaction_data' not in st.session_state:
|
||||||
|
df = pd.DataFrame([[None,None,None,None,None,None,None,None]],columns=[
|
||||||
|
"物质",
|
||||||
|
"分子量",
|
||||||
|
"当量",
|
||||||
|
"用量(mmol)",
|
||||||
|
"质量(g)",
|
||||||
|
"密度(g/mL)",
|
||||||
|
"体积(mL)",
|
||||||
|
"备注"
|
||||||
|
],dtype="float")
|
||||||
|
df["物质"] = df["物质"].astype("string")
|
||||||
|
df["备注"] = df["备注"].astype("string")
|
||||||
|
st.session_state.reaction_data = df
|
||||||
|
|
||||||
st.set_page_config(
|
st.set_page_config(
|
||||||
page_title="有机合成用量计算工具",
|
page_title="有机合成用量计算工具",
|
||||||
page_icon="🧪",
|
page_icon="🧪",
|
||||||
|
Reference in New Issue
Block a user