Spaces:
Running
Running
import json | |
import logging | |
from tempfile import NamedTemporaryFile | |
import gradio as gr | |
import pandas as pd | |
import NDfilter | |
import NDplot | |
from i18n.i18n import I18nAuto | |
logger = logging.getLogger(__name__) | |
logger.setLevel("INFO") | |
i18n = I18nAuto() | |
logger.info(i18n) | |
## 核素筛选 | |
def process_filters(Z_min, Z_max, Z_oe_idx, N_min, N_max, N_oe_idx, A_min, A_max, A_oe_idx, hl_enable_idx, hl_min, hl_min_unit, hl_max, hl_max_unit, dm_enable_idx, decay_modes): | |
filtered_data = NDfilter.nuclidesFilterZNA(nuclides_data, Z_min, Z_max, Z_oe_idx, N_min, N_max, N_oe_idx, A_min, A_max, A_oe_idx) | |
# 根据母核半衰期进行筛选 | |
if hl_enable_idx == 1: | |
hl_min_sec = HLunit_convert(hl_min, hl_min_unit) | |
hl_max_sec = HLunit_convert(hl_max, hl_max_unit) | |
filtered_data = NDfilter.nuclidesFilterHalflife(filtered_data, hl_min_sec, hl_max_sec) | |
# 根据衰变模式进行筛选 | |
if dm_enable_idx > 0 and decay_modes: | |
filtered_data = NDfilter.nuclidesFilterDecayModes(filtered_data, dm_enable_idx, decay_modes) | |
# 结果处理 | |
if len(filtered_data) == 0: | |
result_text = i18n("没有找到符合条件的核素") | |
result_file_path = None | |
else: | |
result_text = i18n("找到符合条件核素数目:") + str(len(filtered_data)) | |
with NamedTemporaryFile(suffix=".json", delete=False, mode='w') as file: | |
json.dump(filtered_data, file, indent=2) | |
result_file_path = file.name | |
return result_text, result_file_path | |
## 核素查找 | |
def process_search(mode_idx, nom, z, n, a, preview_mode, file_type): | |
result = None | |
if mode_idx == 0: | |
result = NDfilter.nuclidesSearchingNom(nuclides_data, nom.replace(" ", "")) | |
elif mode_idx == 1: | |
if not (z == None or n == None): | |
result = NDfilter.nuclidesSearchingZN(nuclides_data, z, n) | |
elif mode_idx == 2: | |
if not (z == None or a == None): | |
result = NDfilter.nuclidesSearchingZA(nuclides_data, z, a) | |
elif mode_idx == 3: | |
if not (n == None or a == None): | |
result = NDfilter.nuclidesSearchingNA(nuclides_data, n, a) | |
## 结果处理 | |
if result == None: | |
result_text = i18n("没有找到此核素") | |
result_dataframe = None | |
result_file_path = None | |
else: | |
## 文本 | |
name = result["name"] | |
result_text = f"{name}" | |
if len(result["levels"]) == 0: | |
result_text = result_text + i18n("\n此核素无数据") | |
result_text = result_text + "\n\n" + i18n("NNDC页面:") + "\n\ngetdataset:\n" + f"https://www.nndc.bnl.gov/nudat3/getdataset.jsp?nucleus={name}&unc=NDS" | |
## temp | |
with open ("data/haveDecayPage.json",'r', encoding='utf-8') as file: | |
haveDecayPage = json.load(file) | |
if haveDecayPage[name]: | |
result_text = result_text + "\n\ndecaysearchdirect:\n" + f"https://www.nndc.bnl.gov/nudat3/decaysearchdirect.jsp?nuc={name}&unc=NDS" | |
## 预览表格 | |
if preview_mode == 0: | |
result_dataframe = NDfilter.nuclideData_dict2dataframeCompact(result) | |
elif preview_mode == 1: | |
result_dataframe = NDfilter.nuclideData_dict2dataframe(result) | |
## 文件 | |
if file_type == 0: | |
with NamedTemporaryFile(suffix=".json", delete=False, mode='w') as file: | |
json.dump(result, file, indent=2) | |
result_file_path = file.name | |
elif file_type == 1: | |
if preview_mode == 1: | |
tmpDataframe = result_dataframe | |
else: | |
tmpDataframe = NDfilter.nuclideData_dict2dataframe(result) | |
with NamedTemporaryFile(suffix=".csv", delete=False, mode='w') as file: | |
tmpDataframe.to_csv(file, index=False) | |
result_file_path = file.name | |
else: | |
result_file_path = None | |
return result_text, result_dataframe, result_file_path | |
## 核素图绘制 | |
def process_plot(plot_mode, text_mode, have_legend_idx, file_type3, using_filter, Z_min=0, Z_max=118, N_min=0, N_max=177): | |
if have_legend_idx == 0: | |
have_legend = True | |
else: | |
have_legend = False | |
area = ((0,0),(118,177)) | |
if using_filter == 1: | |
area = ((Z_min,N_min), (Z_max, N_max)) | |
result_fig = NDplot.nucildesChartPlotPLT(plot_mode, area, text_mode, have_legend) | |
with NamedTemporaryFile(suffix=".svg", delete=False, mode='wb') as file: | |
result_fig.savefig(file, format="svg") | |
preview_svg_path = file.name | |
if file_type3 == "png": | |
with NamedTemporaryFile(suffix=".png", delete=False, mode='wb') as file: | |
result_fig.savefig(file, format="png") | |
result_file_path = file.name | |
elif file_type3 == "svg": | |
result_file_path = preview_svg_path | |
else: | |
result_file_path = None | |
return result_fig, result_file_path | |
## 半衰期单位转换 | |
def HLunit_convert(hl, hl_unit): | |
if hl_unit == "Stable": | |
hl_sec = None | |
else: | |
hl_sec = hl * HL_UNITS[hl_unit] | |
return hl_sec | |
## 处理查找页面输入组件激活情况 | |
def update_inputs2(mode_idx): | |
if mode_idx == 0: # 核素名称模式 | |
return [gr.Textbox(interactive=True), gr.Number(interactive=False, value=None), gr.Number(interactive=False, value=None), gr.Number(interactive=False, value=None)] | |
elif mode_idx == 1: # Z+N模式 | |
return [gr.Textbox(interactive=False, value=None), gr.Number(interactive=True), gr.Number(interactive=True), gr.Number(interactive=False, value=None)] | |
elif mode_idx == 2: # Z+A模式 | |
return [gr.Textbox(interactive=False, value=None), gr.Number(interactive=True), gr.Number(interactive=False, value=None), gr.Number(interactive=True)] | |
elif mode_idx == 3: # N+A模式 | |
return [gr.Textbox(interactive=False, value=None), gr.Number(interactive=False, value=None), gr.Number(interactive=True), gr.Number(interactive=True)] | |
else: | |
return [gr.Textbox(interactive=False, value=None), gr.Number(interactive=False, value=None), gr.Number(interactive=False, value=None), gr.Number(interactive=False, value=None)] | |
def update_inputs3(using_filter): | |
if using_filter == 0: | |
return [gr.Number(interactive=False, value=None)] * 4 | |
elif using_filter == 1: | |
return [gr.Number(interactive=True)] * 4 | |
else: | |
return [gr.Number(interactive=False, value=None)] * 4 | |
## 导入数据集 | |
nuclides_data_path = "data/nndc_nudat_data_export.json" | |
with open (nuclides_data_path,'r', encoding='utf-8') as file: | |
nuclides_data = json.load(file) | |
## 半衰期单位转换字典 | |
HL_UNITS = {"fs": 1e-15, "ps": 1e-12, "ns": 1e-9, "us": 1e-6, "ms": 1e-3, "s": 1, "m": 60, "h": 3600, "d": 86400, "y": 31557600, "ky": 31557600e3, "My": 31557600e6, "Gy": 31557600e9} | |
with gr.Blocks(title=i18n("核数据工具")) as demo: | |
gr.Markdown(i18n("**核数据工具** <br> 可能是用来处理核数据的相关工具?? <br> 目前功能有:核素筛选、核素查找、核素图绘制。")) | |
with gr.Tab(i18n("核素筛选")): | |
gr.Markdown(i18n("**核素筛选** <br> 可以通过质子数(Z)、中子数(N)、质量数(A)以及母核半衰期、衰变模式等进行筛选")) | |
with gr.Row(): | |
with gr.Column(scale=1): | |
gr.Markdown(i18n("根据质子数(Z)、中子数(N)、质量数(A)进行筛选")) | |
with gr.Column(scale=4): | |
with gr.Row(): | |
with gr.Column(min_width=240): | |
gr.Markdown(i18n("质子数(Z)")) | |
Z_min = gr.Number(label=i18n("最小值"), precision=0) | |
Z_max = gr.Number(label=i18n("最大值"), precision=0) | |
Z_oe = gr.Dropdown([i18n("任意"), i18n("奇Z"), i18n("偶Z")], label=i18n("奇偶"), type="index", interactive=True) | |
with gr.Column(min_width=240): | |
gr.Markdown(i18n("中子数(N)")) | |
N_min = gr.Number(label=i18n("最小值"), precision=0) | |
N_max = gr.Number(label=i18n("最大值"), precision=0) | |
N_oe = gr.Dropdown([i18n("任意"), i18n("奇N"), i18n("偶N")], label=i18n("奇偶"), type="index", interactive=True) | |
with gr.Column(min_width=240): | |
gr.Markdown(i18n("质量数(A)")) | |
A_min = gr.Number(label=i18n("最小值"), precision=0) | |
A_max = gr.Number(label=i18n("最大值"), precision=0) | |
A_oe = gr.Dropdown([i18n("任意"), i18n("奇A"), i18n("偶A")], label=i18n("奇偶"), type="index", interactive=True) | |
with gr.Row(): | |
with gr.Column(scale=1): | |
gr.Markdown(i18n("根据母核半衰期进行筛选")) | |
with gr.Column(scale=4): | |
with gr.Row(): | |
hl_enable = gr.Radio([i18n("不使用"), i18n("使用")], value=i18n("不使用"), type="index", show_label=False) | |
hl_min = gr.Number(label=i18n("最小值"), minimum=0.) | |
hl_min_unit = gr.Dropdown(["fs", "ps", "ns", "us", "ms", "s", "m", "h", "d", "y", "ky", "My", "Gy", "Stable"], value="fs", interactive=True, label=" ") | |
hl_max = gr.Number(label=i18n("最大值"), minimum=0.) | |
hl_max_unit = gr.Dropdown(["fs", "ps", "ns", "us", "ms", "s", "m", "h", "d", "y", "ky", "My", "Gy", "Stable"], value="Stable", interactive=True, label=" ") | |
with gr.Row(): | |
with gr.Column(scale=1): | |
gr.Markdown(i18n("根据衰变模式进行筛选")) | |
with gr.Column(scale=4): | |
with gr.Row(): | |
dm_enable_idx = gr.Radio([i18n("不使用"), i18n("筛选包含所有以下所选衰变模式的核素(and)"), i18n("筛选包含任意以下所选衰变模式的核素(or)")], value=i18n("不使用"), type="index", interactive=True, show_label=False) | |
with gr.Row(): | |
decayModes = gr.CheckboxGroup(['B-', 'N', '2N', 'B-N', 'P', 'B-A', 'B-2N', 'B-3N', '2P', 'EC', 'A', 'B-4N', 'EC+B+', 'ECA', 'ECP', 'IT', 'EC2P', 'EC3P', 'ECAP', '3P', '2B-', 'ECSF', '14C', 'B-SF', '24NE', 'SF', '20O', '20NE', '25NE', '28MG', 'NE', '22NE', 'SI', 'MG', '34SI'], label=i18n("衰变模式"), interactive=True) | |
with gr.Row(): | |
submit_btn = gr.Button(i18n("筛选"), variant="primary") | |
reset_btn = gr.Button(i18n("重置条件"), variant="primary") | |
with gr.Row(): | |
result_text = gr.Textbox(label=i18n("筛选结果"), interactive=False, show_copy_button=True) | |
result_file = gr.File(label=i18n("结果文件"), interactive=False) | |
inputs = [ | |
Z_min, Z_max, Z_oe, | |
N_min, N_max, N_oe, | |
A_min, A_max, A_oe, | |
hl_enable, hl_min, hl_min_unit, hl_max, hl_max_unit, | |
dm_enable_idx, decayModes | |
] | |
submit_btn.click( | |
fn=process_filters, | |
inputs=inputs, | |
outputs=[result_text, result_file] | |
) | |
reset_btn.click( | |
fn=lambda: [None,None,i18n("任意")]*3 + [i18n("不使用"), None, "fs", None, "Stable"] + [i18n("不使用"), []], | |
outputs=inputs | |
) | |
with gr.Tab(i18n("核素查找")): | |
gr.Markdown(i18n("**核素查找**")) | |
with gr.Row(): | |
with gr.Column(scale=3): | |
searchingMode = gr.Radio([i18n("核素名称"), i18n("质子数(Z)、中子数(N)"), i18n("质子数(Z)、质量数(A)"), i18n("中子数(N)、质量数(A)")], value=i18n("核素名称"), label=i18n("查找模式"), interactive=True, type="index") | |
gr.Markdown(i18n("**根据核素名称查找**")) | |
nuclide_in = gr.Textbox(value=None, show_label=False, info=i18n("请输入由质量数及元素名称所组成的核素名称,示例:232Th、232TH、th232、232-Th、th-232等。\n只要不太离谱就能识别……大概?")) | |
gr.Markdown(i18n("**根据质子数(Z)、中子数(N)、质量数(A)查找**")) | |
with gr.Row(): | |
Z_in = gr.Number(value=0, label=i18n("质子数(Z)"), precision=0, interactive=False) | |
N_in = gr.Number(value=0, label=i18n("中子数(N)"), precision=0, interactive=False) | |
A_in = gr.Number(value=0, label=i18n("质量数(A)"), precision=0, interactive=False) | |
previewMode = gr.Radio([i18n("紧凑"), i18n("常规")], value=i18n("紧凑"), type="index", label=i18n("预览模式")) | |
outputFileType = gr.Radio(["json", "csv"], value="json", type="index", label=i18n("导出文件格式")) | |
with gr.Row(): | |
submit_btn2 = gr.Button(i18n("查找"), variant="primary") | |
reset_btn2 = gr.Button(i18n("重置条件"), variant="primary") | |
with gr.Column(scale=2): | |
result_text2 = gr.Textbox(interactive=False, show_label=False) | |
preview_df = gr.Dataframe(label=i18n("数据预览"), interactive=False) | |
result_file2 = gr.File(label=i18n("结果文件"), interactive=False) | |
searchingMode.change( | |
fn=update_inputs2, | |
inputs=searchingMode, | |
outputs=[nuclide_in, Z_in, N_in, A_in] | |
) | |
inputs2 = [ | |
searchingMode, | |
nuclide_in, | |
Z_in, N_in, A_in, | |
previewMode, outputFileType | |
] | |
submit_btn2.click( | |
fn=process_search, | |
inputs=inputs2, | |
outputs=[result_text2, preview_df, result_file2] | |
) | |
reset_btn2.click( | |
fn=lambda: [None]*4, | |
outputs=[nuclide_in, Z_in, N_in, A_in] | |
) | |
with gr.Tab(i18n("核素图绘制")): | |
gr.Markdown(i18n("**核素图绘制** <br> 可根据半衰期、衰变模式、合成方法等分类模式绘制核素图。 <br>部分代码参考了Ming-Hao-Zhang的[Nuclei-Chart-Generator](https://github.com/Ming-Hao-Zhang/Nuclei-Chart-Generator)")) | |
with gr.Row(): | |
with gr.Column(scale=3): | |
img_preview = gr.Plot(label=i18n("图片预览")) | |
with gr.Column(scale=2): | |
plot_mode = gr.Radio([i18n("寿命"), i18n("衰变模式"), i18n("合成方法")], value=i18n("寿命"), label=i18n("核素分类模式"), type="index") | |
text_mode = gr.Radio([i18n("无"), i18n("元素名称"), i18n("核素名称"), i18n("详细信息")], value=i18n("无"), label=i18n("显示信息"), type="index") | |
have_legend_idx = gr.Radio([i18n("显示图例"), i18n("隐藏图例")], value=i18n("显示图例"), label=i18n("图例"), type="index") | |
file_type3 = gr.Radio(["svg", "png"], value="svg", label=i18n("导出格式"), info=i18n("png为位图格式,svg为矢量图格式。\n显示详细信息时,受分辨率限制,png格式将会失真。如需高清晰度图像,请使用svg。")) | |
with gr.Accordion(open=False, label=i18n("更多选项")) as filter3: | |
gr.Markdown(i18n("根据质子数(Z)、中子数(N)筛选 (未启用)")) | |
using_filter = gr.Radio([i18n("不使用"), i18n("使用")], value=i18n("不使用"), show_label=False, type='index', interactive=False) | |
with gr.Row(): | |
with gr.Column(min_width=120): | |
gr.Markdown(i18n("质子数(Z)")) | |
Z_min = gr.Number(label=i18n("最小值"), precision=0, interactive=False) | |
Z_max = gr.Number(label=i18n("最大值"), precision=0, interactive=False) | |
with gr.Column(min_width=120): | |
gr.Markdown(i18n("中子数(N)")) | |
N_min = gr.Number(label=i18n("最小值"), precision=0, interactive=False) | |
N_max = gr.Number(label=i18n("最大值"), precision=0, interactive=False) | |
with gr.Row(): | |
submit_btn3 = gr.Button(i18n("绘制"), variant="primary") | |
reset_btn3 = gr.Button(i18n("重置条件"), variant="primary") | |
result_file3 = gr.File(label=i18n("结果文件"), interactive=False) | |
using_filter.change( | |
fn=update_inputs3, | |
inputs=using_filter, | |
outputs=[Z_min, Z_max, N_min, N_max] | |
) | |
filter3.collapse( | |
fn=lambda: i18n("不使用"), | |
outputs= using_filter | |
) | |
inputs3 = [plot_mode, text_mode, have_legend_idx, file_type3, using_filter, Z_min, Z_max, N_min, N_max] | |
submit_btn3.click( | |
fn=process_plot, | |
inputs=inputs3, | |
outputs=[img_preview, result_file3] | |
) | |
reset_btn3.click( | |
fn=lambda: [i18n("寿命"), i18n("无"), i18n("显示图例"), "svg", i18n("不使用")] + [None]*4, | |
outputs=inputs3 | |
) | |
demo.launch() |