Spaces:
Sleeping
Sleeping
Wanlau
commited on
Commit
·
a4ef31a
1
Parent(s):
013b032
NDplot
Browse files- .gitignore +2 -0
- NDfilter.py +180 -9
- NDplot.py +468 -0
- app.py +348 -255
- data/ElementsList.json +1 -0
- data/NuclidesClassifiedDecayModes.json +0 -0
- data/NuclidesClassifiedHalflife.json +0 -0
- data/Nuclides_synthesisMethods.json +0 -0
.gitignore
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
|
|
|
| 1 |
+
__pycache__/*
|
| 2 |
+
.vscode/*
|
NDfilter.py
CHANGED
|
@@ -6,6 +6,7 @@ import pandas as pd
|
|
| 6 |
|
| 7 |
## 半衰期单位转换字典
|
| 8 |
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}
|
|
|
|
| 9 |
|
| 10 |
def nuclidesFilterZNA(nuclides_data, Z_min=None, Z_max=None, Z_oe_idx=0, N_min=None, N_max=None, N_oe_idx=0, A_min=None, A_max=None, A_oe_idx=0):
|
| 11 |
filtered = {}
|
|
@@ -186,14 +187,59 @@ def nuclideData_dict2dataframe(nuclideData_dict):
|
|
| 186 |
a = nuclideData_dict["a"]
|
| 187 |
data = []
|
| 188 |
for level in nuclideData_dict["levels"]:
|
| 189 |
-
|
| 190 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 191 |
else:
|
| 192 |
hl = level["halflife"]["value"]
|
| 193 |
hl_unit = level["halflife"]["unit"]
|
| 194 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 195 |
for decayMode in level["decayModes"]["observed"]:
|
| 196 |
-
data.append((nom, z, n, a, level["energy"]["value"], level["energy"]["unit"],
|
| 197 |
|
| 198 |
nuclideDataframe = pd.DataFrame(data, columns=["Nuclide", "Z", "N", "A", "E(level)", "E(level) unit", "Spin Parity", "Mass Excess", "Mass Excess unit", "Mass Excess uncertainty", "Halflife", "Halflife unit", "Halflife uncertainty", "Decay Mode", "Branch Ratio"])
|
| 199 |
|
|
@@ -202,18 +248,143 @@ def nuclideData_dict2dataframe(nuclideData_dict):
|
|
| 202 |
def nuclideData_dict2dataframeCompact(nuclideData_dict):
|
| 203 |
data = []
|
| 204 |
for level in nuclideData_dict["levels"]:
|
| 205 |
-
|
| 206 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 207 |
else:
|
| 208 |
decayModes = []
|
| 209 |
for decayMode in level["decayModes"]["observed"]:
|
| 210 |
decayModes.append((decayMode["mode"], decayMode["value"]))
|
| 211 |
decayModeDF = pd.DataFrame(decayModes, columns=["Decay Mode", "Branch Ratio"])
|
| 212 |
-
data.append((str(level["energy"]["value"])+" "+level["energy"]["unit"],
|
| 213 |
|
| 214 |
nuclideDataframe = pd.DataFrame(data, columns=["E(level)", "Spin Parity", "Mass Excess", "Halflife", "Decay Modes"])
|
| 215 |
|
| 216 |
return nuclideDataframe
|
| 217 |
|
| 218 |
-
|
| 219 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 6 |
|
| 7 |
## 半衰期单位转换字典
|
| 8 |
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}
|
| 9 |
+
nuclides_data_path = "data/nndc_nudat_data_export.json"
|
| 10 |
|
| 11 |
def nuclidesFilterZNA(nuclides_data, Z_min=None, Z_max=None, Z_oe_idx=0, N_min=None, N_max=None, N_oe_idx=0, A_min=None, A_max=None, A_oe_idx=0):
|
| 12 |
filtered = {}
|
|
|
|
| 187 |
a = nuclideData_dict["a"]
|
| 188 |
data = []
|
| 189 |
for level in nuclideData_dict["levels"]:
|
| 190 |
+
## 自旋宇称
|
| 191 |
+
spinParity = None
|
| 192 |
+
if "spinParity" in level:
|
| 193 |
+
spinParity = level["spinParity"]
|
| 194 |
+
|
| 195 |
+
## 质量过剩
|
| 196 |
+
massExcess = None
|
| 197 |
+
massExcess_unit = None
|
| 198 |
+
massExcess_unc = None
|
| 199 |
+
if not "massExcess" in level:
|
| 200 |
+
pass
|
| 201 |
+
else:
|
| 202 |
+
massExcess = level["massExcess"]["unit"]
|
| 203 |
+
massExcess_unit = level["massExcess"]["value"]
|
| 204 |
+
massExcess_unc = level["massExcess"]["uncertainty"]
|
| 205 |
+
|
| 206 |
+
## 半衰期
|
| 207 |
+
hl = None
|
| 208 |
+
hl_unit = None
|
| 209 |
+
hl_unc = None
|
| 210 |
+
if not "halflife" in level:
|
| 211 |
+
pass
|
| 212 |
+
elif level["halflife"]["value"] == "STABLE":
|
| 213 |
+
pass
|
| 214 |
else:
|
| 215 |
hl = level["halflife"]["value"]
|
| 216 |
hl_unit = level["halflife"]["unit"]
|
| 217 |
+
if level["halflife"]["uncertainty"]["type"] == "asymmetric":
|
| 218 |
+
hl_unc = "+" + str(level["halflife"]["uncertainty"]["upperLimit"]) + " -" + str(level["halflife"]["uncertainty"]["lowerLimit"])
|
| 219 |
+
elif level["halflife"]["uncertainty"]["type"] == "approximation":
|
| 220 |
+
hl_unc = "≈"
|
| 221 |
+
elif level["halflife"]["uncertainty"]["type"] == "limit":
|
| 222 |
+
if level["halflife"]["uncertainty"]["limitType"] == "lower":
|
| 223 |
+
if level["halflife"]["uncertainty"]["isInclusive"] == True:
|
| 224 |
+
hl_unc = "≥"
|
| 225 |
+
else:
|
| 226 |
+
hl_unc = ">"
|
| 227 |
+
elif level["halflife"]["uncertainty"]["limitType"] == "upper":
|
| 228 |
+
if level["halflife"]["uncertainty"]["isInclusive"] == True:
|
| 229 |
+
hl_unc = "≤"
|
| 230 |
+
else:
|
| 231 |
+
hl_unc = "<"
|
| 232 |
+
else:
|
| 233 |
+
hl_unc = level["halflife"]["uncertainty"]["value"]
|
| 234 |
+
|
| 235 |
+
## 衰变模式
|
| 236 |
+
if not "decayModes" in level:
|
| 237 |
+
data.append((nom, z, n, a, level["energy"]["value"], level["energy"]["unit"], spinParity, massExcess, massExcess_unit, massExcess_unc, hl, hl_unit, hl_unc, None, None))
|
| 238 |
+
elif len(level["decayModes"]["observed"]) == 0:
|
| 239 |
+
data.append((nom, z, n, a, level["energy"]["value"], level["energy"]["unit"], spinParity, massExcess, massExcess_unit, massExcess_unc, hl, hl_unit, hl_unc, None, None))
|
| 240 |
+
else:
|
| 241 |
for decayMode in level["decayModes"]["observed"]:
|
| 242 |
+
data.append((nom, z, n, a, level["energy"]["value"], level["energy"]["unit"], spinParity, massExcess, massExcess_unit, massExcess_unc, hl, hl_unit, hl_unc, decayMode["mode"], decayMode["value"]))
|
| 243 |
|
| 244 |
nuclideDataframe = pd.DataFrame(data, columns=["Nuclide", "Z", "N", "A", "E(level)", "E(level) unit", "Spin Parity", "Mass Excess", "Mass Excess unit", "Mass Excess uncertainty", "Halflife", "Halflife unit", "Halflife uncertainty", "Decay Mode", "Branch Ratio"])
|
| 245 |
|
|
|
|
| 248 |
def nuclideData_dict2dataframeCompact(nuclideData_dict):
|
| 249 |
data = []
|
| 250 |
for level in nuclideData_dict["levels"]:
|
| 251 |
+
## 自旋宇称
|
| 252 |
+
spinParity = None
|
| 253 |
+
if "spinParity" in level:
|
| 254 |
+
spinParity = level["spinParity"]
|
| 255 |
+
|
| 256 |
+
## 质量过剩
|
| 257 |
+
massExcess = None
|
| 258 |
+
if not "massExcess" in level:
|
| 259 |
+
pass
|
| 260 |
+
else:
|
| 261 |
+
massExcess = level["massExcess"]["formats"]["NDS"]+" "+level["massExcess"]["unit"]
|
| 262 |
+
|
| 263 |
+
## 半衰期
|
| 264 |
+
hl = None
|
| 265 |
+
if not "halflife" in level:
|
| 266 |
+
pass
|
| 267 |
+
elif level["halflife"]["value"] == "STABLE":
|
| 268 |
+
hl = "STABLE"
|
| 269 |
+
else:
|
| 270 |
+
hl = level["halflife"]["formats"]["NDS"]+" "+level["halflife"]["unit"]
|
| 271 |
+
|
| 272 |
+
## 衰变模式
|
| 273 |
+
if not "decayModes" in level:
|
| 274 |
+
data.append((str(level["energy"]["value"])+" "+level["energy"]["unit"], spinParity, massExcess, hl, None))
|
| 275 |
+
elif len(level["decayModes"]["observed"]) == 0:
|
| 276 |
+
data.append((str(level["energy"]["value"])+" "+level["energy"]["unit"], spinParity, massExcess, hl, None))
|
| 277 |
else:
|
| 278 |
decayModes = []
|
| 279 |
for decayMode in level["decayModes"]["observed"]:
|
| 280 |
decayModes.append((decayMode["mode"], decayMode["value"]))
|
| 281 |
decayModeDF = pd.DataFrame(decayModes, columns=["Decay Mode", "Branch Ratio"])
|
| 282 |
+
data.append((str(level["energy"]["value"])+" "+level["energy"]["unit"], spinParity, massExcess, hl, decayModeDF))
|
| 283 |
|
| 284 |
nuclideDataframe = pd.DataFrame(data, columns=["E(level)", "Spin Parity", "Mass Excess", "Halflife", "Decay Modes"])
|
| 285 |
|
| 286 |
return nuclideDataframe
|
| 287 |
|
| 288 |
+
def nuclidesClassifyHalflife(data_path):
|
| 289 |
+
with open (data_path,'r', encoding='utf-8') as file:
|
| 290 |
+
nuclides_data = json.load(file)
|
| 291 |
+
|
| 292 |
+
classified = []
|
| 293 |
+
for nom, data in nuclides_data.items():
|
| 294 |
+
z = data["z"]
|
| 295 |
+
n = data["n"]
|
| 296 |
+
hl_type = "UN"
|
| 297 |
+
|
| 298 |
+
if len(data["levels"]) == 0:
|
| 299 |
+
hl_type = "UN"
|
| 300 |
+
elif not "halflife" in data["levels"][0]:
|
| 301 |
+
hl_type = "UN"
|
| 302 |
+
elif data["levels"][0]["halflife"]["value"] == "STABLE":
|
| 303 |
+
hl_type = "ST"
|
| 304 |
+
elif not data["levels"][0]["halflife"]["unit"] in HL_UNITS:
|
| 305 |
+
hl_type = "SU"
|
| 306 |
+
else:
|
| 307 |
+
hl_sec = data["levels"][0]["halflife"]["value"] * HL_UNITS[data["levels"][0]["halflife"]["unit"]]
|
| 308 |
+
if hl_sec < 1e-7:
|
| 309 |
+
hl_type = "l100ns"
|
| 310 |
+
elif hl_sec < 1e-6:
|
| 311 |
+
hl_type = "100ns"
|
| 312 |
+
elif hl_sec < 1e-5:
|
| 313 |
+
hl_type = "1us"
|
| 314 |
+
elif hl_sec < 1e-4:
|
| 315 |
+
hl_type = "10us"
|
| 316 |
+
elif hl_sec < 1e-3:
|
| 317 |
+
hl_type = "100us"
|
| 318 |
+
elif hl_sec < 1e-2:
|
| 319 |
+
hl_type = "1ms"
|
| 320 |
+
elif hl_sec < 1e-1:
|
| 321 |
+
hl_type = "10ms"
|
| 322 |
+
elif hl_sec < 1:
|
| 323 |
+
hl_type = "100ms"
|
| 324 |
+
elif hl_sec < 10:
|
| 325 |
+
hl_type = "1s"
|
| 326 |
+
elif hl_sec < 100:
|
| 327 |
+
hl_type = "10s"
|
| 328 |
+
elif hl_sec < 1e3:
|
| 329 |
+
hl_type = "100s"
|
| 330 |
+
elif hl_sec < 1e4:
|
| 331 |
+
hl_type = "1ks"
|
| 332 |
+
elif hl_sec < 1e5:
|
| 333 |
+
hl_type = "10ks"
|
| 334 |
+
elif hl_sec < 1e7:
|
| 335 |
+
hl_type = "100ks"
|
| 336 |
+
elif hl_sec < 1e10:
|
| 337 |
+
hl_type = "10Ms"
|
| 338 |
+
elif hl_sec < 1e15:
|
| 339 |
+
hl_type = "1e10s"
|
| 340 |
+
else:
|
| 341 |
+
hl_type = "1e15s"
|
| 342 |
+
|
| 343 |
+
classified.append({"z":z, "n":n, "type":hl_type})
|
| 344 |
+
|
| 345 |
+
return classified
|
| 346 |
+
|
| 347 |
+
def nuclidesClassifyDecayMode(data_path):
|
| 348 |
+
with open (data_path,'r', encoding='utf-8') as file:
|
| 349 |
+
nuclides_data = json.load(file)
|
| 350 |
+
|
| 351 |
+
classified = []
|
| 352 |
+
for nom, data in nuclides_data.items():
|
| 353 |
+
z = data["z"]
|
| 354 |
+
n = data["n"]
|
| 355 |
+
dm_type = "UNKNOWN"
|
| 356 |
+
|
| 357 |
+
if len(data["levels"]) == 0:
|
| 358 |
+
dm_type = "UNKNOWN"
|
| 359 |
+
elif not "decayModes" in data["levels"][0]:
|
| 360 |
+
dm_type = "UNKNOWN"
|
| 361 |
+
if "halflife" in data["levels"][0]:
|
| 362 |
+
if data["levels"][0]["halflife"]["value"] == "STABLE":
|
| 363 |
+
dm_type = "STABLE"
|
| 364 |
+
else:
|
| 365 |
+
decay_modes = data["levels"][0]["decayModes"]["observed"] + data["levels"][0]["decayModes"]["predicted"]
|
| 366 |
+
if len(decay_modes) == 0:
|
| 367 |
+
dm_type = "UNKNOWN"
|
| 368 |
+
else:
|
| 369 |
+
## 据分支比排序
|
| 370 |
+
dms1 = []
|
| 371 |
+
dms2 = []
|
| 372 |
+
dmsd = {}
|
| 373 |
+
dmsd1 = []
|
| 374 |
+
for decay_mode in decay_modes:
|
| 375 |
+
if not "value" in decay_mode:
|
| 376 |
+
dms2.append(decay_mode)
|
| 377 |
+
else:
|
| 378 |
+
dmsd[decay_mode["mode"]] = decay_mode
|
| 379 |
+
dmsd1.append((decay_mode["value"], decay_mode["mode"]))
|
| 380 |
+
dmsdf = pd.DataFrame(dmsd1, columns=["value", "mode"])
|
| 381 |
+
dmsdf.sort_values(by="value", ascending=False, inplace=True)
|
| 382 |
+
for mode in dmsdf["mode"]:
|
| 383 |
+
dms1.append(dmsd[mode])
|
| 384 |
+
dms = dms1 + dms2
|
| 385 |
+
dm_type = dms[0]["mode"]
|
| 386 |
+
classified.append({"z":z, "n":n, "type":dm_type})
|
| 387 |
+
|
| 388 |
+
return classified
|
| 389 |
+
|
| 390 |
+
##test
|
NDplot.py
ADDED
|
@@ -0,0 +1,468 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import copy
|
| 2 |
+
import json
|
| 3 |
+
import math
|
| 4 |
+
import re
|
| 5 |
+
import numpy as np
|
| 6 |
+
import pandas as pd
|
| 7 |
+
import matplotlib.pyplot as plt
|
| 8 |
+
#import matplotlib.colors as mcolors
|
| 9 |
+
from matplotlib.patches import Patch
|
| 10 |
+
|
| 11 |
+
## the synthesis methods: Mass Spectroscopy, Radioactive Decay, Light Particles, Fission, Fusion, Spallation, Projectile Fragmentation, and Transfer/Deep Inelastic Scattering
|
| 12 |
+
colors_synthesisMethods = {
|
| 13 |
+
"MS" : (0, 0, 0),
|
| 14 |
+
"RD" : (0, 255, 255),
|
| 15 |
+
"LP" : (255, 165, 0),
|
| 16 |
+
"FI" : (255, 255, 0),
|
| 17 |
+
"FU" : (255, 0, 0),
|
| 18 |
+
"SP" : (0, 0, 255),
|
| 19 |
+
"PF" : (0, 127, 0),
|
| 20 |
+
"UN" : (127, 0, 127)
|
| 21 |
+
}
|
| 22 |
+
|
| 23 |
+
names_synthesisMethods = {
|
| 24 |
+
"MS" : "Mass Spectroscopy",
|
| 25 |
+
"RD" : "Radioactive Decay",
|
| 26 |
+
"LP" : "Light Particles",
|
| 27 |
+
"FI" : "Fission",
|
| 28 |
+
"FU" : "Fusion",
|
| 29 |
+
"SP" : "Spallation",
|
| 30 |
+
"PF" : "Projectile Fragmentation",
|
| 31 |
+
"UN" : "Transfer/Deep Inelastic"
|
| 32 |
+
}
|
| 33 |
+
|
| 34 |
+
colors_halflife = {
|
| 35 |
+
"l100ns": (247, 189, 222),
|
| 36 |
+
"100ns" : (255, 198, 165),
|
| 37 |
+
"1us" : (255, 231, 198),
|
| 38 |
+
"10us" : (255, 255, 156),
|
| 39 |
+
"100us" : (255, 255, 16),
|
| 40 |
+
"1ms" : (231, 247, 132),
|
| 41 |
+
"10ms" : (214, 239, 57),
|
| 42 |
+
"100ms" : (173, 222, 99),
|
| 43 |
+
"1s" : (82, 181, 82),
|
| 44 |
+
"10s" : (99, 189, 181),
|
| 45 |
+
"100s" : (99, 198, 222),
|
| 46 |
+
"1ks" : (0, 165, 198),
|
| 47 |
+
"10ks" : (8, 154, 148),
|
| 48 |
+
"100ks" : (0, 132, 165),
|
| 49 |
+
"10Ms" : (49, 82, 165),
|
| 50 |
+
"1e10s" : (41, 0, 107),
|
| 51 |
+
"1e15s" : (0, 0, 0),
|
| 52 |
+
"ST" : (0, 0, 0),
|
| 53 |
+
"SU" : (255, 148, 115),
|
| 54 |
+
"UN" : (224, 224, 224)
|
| 55 |
+
}
|
| 56 |
+
|
| 57 |
+
legends_halflife = {
|
| 58 |
+
"l100ns": "<100ns",
|
| 59 |
+
"100ns" : "100ns ~ 1us",
|
| 60 |
+
"1us" : "1us ~ 10us",
|
| 61 |
+
"10us" : "10us ~ 100us",
|
| 62 |
+
"100us" : "100us ~ 1ms",
|
| 63 |
+
"1ms" : "1ms ~ 10ms",
|
| 64 |
+
"10ms" : "10ms ~ 100ms",
|
| 65 |
+
"100ms" : "100ms ~ 1s",
|
| 66 |
+
"1s" : "1s ~ 10s",
|
| 67 |
+
"10s" : "10s ~ 100s",
|
| 68 |
+
"100s" : "100s ~ 1ks",
|
| 69 |
+
"1ks" : "1ks ~ 10ks",
|
| 70 |
+
"10ks" : "10ks ~ 100ks",
|
| 71 |
+
"100ks" : "100ks ~ 10Ms",
|
| 72 |
+
"10Ms" : "10Ms ~ 1e10s",
|
| 73 |
+
"1e10s" : "1e10s ~ 1e15s",
|
| 74 |
+
"1e15s" : ">1e15s",
|
| 75 |
+
"ST" : "STABLE",
|
| 76 |
+
"SU" : "SpecialUnit",
|
| 77 |
+
"UN" : "UNKNOWN"
|
| 78 |
+
}
|
| 79 |
+
|
| 80 |
+
colors_DecayModes = {
|
| 81 |
+
"P" : (255, 148, 115),
|
| 82 |
+
"N" : (156, 123, 189),
|
| 83 |
+
"A" : (255, 255, 66),
|
| 84 |
+
"B-" : (231, 140, 198),
|
| 85 |
+
"EC+B+" : (99, 198, 222),
|
| 86 |
+
"EC" : (0, 132, 165),
|
| 87 |
+
"SF" : (82, 181, 82),
|
| 88 |
+
"STABLE": (0, 0, 0),
|
| 89 |
+
"UNKNOWN":(224, 224, 224)
|
| 90 |
+
}
|
| 91 |
+
|
| 92 |
+
legends_DecayModes = {
|
| 93 |
+
"P" : "Proton",
|
| 94 |
+
"N" : "Neutron",
|
| 95 |
+
"A" : "Alaph",
|
| 96 |
+
"B-" : "Beta-",
|
| 97 |
+
"EC+B+" : "Beta+ ElectronCapture",
|
| 98 |
+
"EC" : "ElectronCapture",
|
| 99 |
+
"SF" : "SpontaneousFission",
|
| 100 |
+
"STABLE": "STABLE",
|
| 101 |
+
"UNKNOWN":"UNKNOWN"
|
| 102 |
+
}
|
| 103 |
+
|
| 104 |
+
nuclides_data_path = "data/nndc_nudat_data_export.json"
|
| 105 |
+
data_synthesisMethods_path = "data/Nuclides_synthesisMethods.json"
|
| 106 |
+
ElementsList_path = "data/ElementsList.json"
|
| 107 |
+
data_NuclidesClassifiedHalflife_path = "data/NuclidesClassifiedHalflife.json"
|
| 108 |
+
data_NuclidesClassifiedDecayModes_path = "data/NuclidesClassifiedDecayModes.json"
|
| 109 |
+
|
| 110 |
+
## 使用matplotlib绘图
|
| 111 |
+
## 入参为核素分类模式、所绘制核素区域、显示信息、有无图例
|
| 112 |
+
## area部分待完善
|
| 113 |
+
def nucildesChartPlotPLT(plot_mode=0, area=((0,0),(118,177)), text_mode=0, have_legend=True):
|
| 114 |
+
## 确定绘制核素区域
|
| 115 |
+
z_min, n_min = area[0]
|
| 116 |
+
z_max, n_max = area[1]
|
| 117 |
+
area_ysize = z_max - z_min + 1
|
| 118 |
+
area_xsize = n_max - n_min + 1
|
| 119 |
+
|
| 120 |
+
## 计算坐标时使用的单位为像素,而matplotlib的方法使用的单位为英寸,执行前须进行单位转换
|
| 121 |
+
nbwidth = 40
|
| 122 |
+
nbheight = 40
|
| 123 |
+
dpi = 100
|
| 124 |
+
|
| 125 |
+
## 根据显示信息确定绘图大小
|
| 126 |
+
if text_mode == 0:
|
| 127 |
+
resize_ratio = 5
|
| 128 |
+
ticks_step = 10
|
| 129 |
+
fontsize_label = 75
|
| 130 |
+
fontsize_ticks = 50
|
| 131 |
+
elif text_mode == 1:
|
| 132 |
+
resize_ratio = 5
|
| 133 |
+
ticks_step = 10
|
| 134 |
+
fontsize_label = 75
|
| 135 |
+
fontsize_ticks = 50
|
| 136 |
+
elif text_mode == 2:
|
| 137 |
+
resize_ratio = 10
|
| 138 |
+
ticks_step = 10
|
| 139 |
+
fontsize_label = 150
|
| 140 |
+
fontsize_ticks = 100
|
| 141 |
+
elif text_mode == 3:
|
| 142 |
+
resize_ratio = 10
|
| 143 |
+
ticks_step = 10
|
| 144 |
+
fontsize_label = 150
|
| 145 |
+
fontsize_ticks = 100
|
| 146 |
+
else:
|
| 147 |
+
resize_ratio = 1
|
| 148 |
+
ticks_step = 10
|
| 149 |
+
fontsize_label = 15
|
| 150 |
+
fontsize_ticks = 10
|
| 151 |
+
|
| 152 |
+
## 确定绘制范围
|
| 153 |
+
## 据质子数、中子数取整十
|
| 154 |
+
## 对于默认的(118,177),绘制范围为(130, 200)
|
| 155 |
+
x_min = math.floor(n_min / 10) * 10
|
| 156 |
+
x_max = math.ceil(n_max / 10) * 10
|
| 157 |
+
y_min = math.floor(z_min / 10) * 10
|
| 158 |
+
y_max = math.ceil(z_max / 10) * 10
|
| 159 |
+
|
| 160 |
+
fig = plt.figure(figsize=(10*resize_ratio*(x_max-x_min)/200, 6*resize_ratio*(y_max-y_min)/130), dpi=dpi)
|
| 161 |
+
ax = plt.gca()
|
| 162 |
+
|
| 163 |
+
|
| 164 |
+
## 核素区域绘制,默认白色背景
|
| 165 |
+
bg_color = (255, 255, 255)
|
| 166 |
+
color_data = np.full((area_ysize, area_xsize, 3), bg_color)
|
| 167 |
+
|
| 168 |
+
dx = nbwidth * resize_ratio
|
| 169 |
+
dy = nbheight * resize_ratio
|
| 170 |
+
xposg = np.arange(0, area_xsize*dx + dx, dx)
|
| 171 |
+
yposg = np.arange(0, area_ysize*dy + dy, dy)
|
| 172 |
+
|
| 173 |
+
xgrid = np.tile(xposg.reshape(1, -1), (area_ysize + 1, 1))
|
| 174 |
+
ygrid = np.tile(yposg.reshape(-1, 1), (1, area_xsize + 1))
|
| 175 |
+
|
| 176 |
+
xgridI = xgrid / dpi
|
| 177 |
+
ygridI = ygrid / dpi
|
| 178 |
+
|
| 179 |
+
## 根据核素分类模式上色
|
| 180 |
+
color_data = nucildesChartPlotPLTColor(copy.deepcopy(color_data), plot_mode, z_min, n_min ,z_max, n_max)
|
| 181 |
+
|
| 182 |
+
## 停用imshow转用pcolormesh以便控制各网格大小以及绘制边框
|
| 183 |
+
#ax.imshow(color_data, origin="lower", extent=[n_min-0.5, n_max+0.5, z_min-0.5, z_max+0.5])
|
| 184 |
+
ax.pcolormesh(xgridI, ygridI, color_data.astype(np.uint8), edgecolors="white", linewidth=4*resize_ratio/dpi)
|
| 185 |
+
|
| 186 |
+
|
| 187 |
+
## 绘制坐标轴
|
| 188 |
+
ax.set_xlim(((x_min-5)*dx/dpi, (x_max+20)*dx/dpi))
|
| 189 |
+
ax.set_ylim(((y_min-5)*dy/dpi, (y_max+10)*dy/dpi))
|
| 190 |
+
ax.set_xlabel("Neutron number", fontsize=fontsize_label, font='Times New Roman')
|
| 191 |
+
ax.set_ylabel("Proton number" , fontsize=fontsize_label, font='Times New Roman')
|
| 192 |
+
|
| 193 |
+
## 刻度绘制,同样取整十 (ticks_step = 10)
|
| 194 |
+
xticks = np.arange(x_min, x_max + 20 + ticks_step, ticks_step)
|
| 195 |
+
yticks = np.arange(y_min, y_max + 10 + ticks_step, ticks_step)
|
| 196 |
+
xtickspos = (xticks * dx + np.ones(len(xticks)) * 0.5 * dx) / dpi
|
| 197 |
+
ytickspos = (yticks * dy + np.ones(len(yticks)) * 0.5 * dy) / dpi
|
| 198 |
+
ax.set_xticks(xtickspos, xticks, fontsize=fontsize_ticks)
|
| 199 |
+
ax.set_yticks(ytickspos, yticks, fontsize=fontsize_ticks)
|
| 200 |
+
|
| 201 |
+
## 图例添加
|
| 202 |
+
## 默认大小匹配全图绘制
|
| 203 |
+
if have_legend:
|
| 204 |
+
legend_handles = legendHandlesGet(plot_mode)
|
| 205 |
+
if len(legend_handles) < 13:
|
| 206 |
+
fontsize_legend = fontsize_ticks
|
| 207 |
+
else:
|
| 208 |
+
fontsize_legend = fontsize_ticks * 0.6
|
| 209 |
+
plt.legend(handles=legend_handles, loc="lower right", fontsize=fontsize_legend)
|
| 210 |
+
|
| 211 |
+
## 添加显示信息
|
| 212 |
+
if not text_mode == 0:
|
| 213 |
+
color_weight = np.array((0.299, 0.587, 0.114))
|
| 214 |
+
text_data = nucildesChartPlotPLTText(plot_mode, z_min, n_min ,z_max, n_max)
|
| 215 |
+
|
| 216 |
+
## 显示元素名称
|
| 217 |
+
if text_mode == 1:
|
| 218 |
+
for tdata in text_data:
|
| 219 |
+
## 根据方块颜色选择文本颜色(黑或白)
|
| 220 |
+
base_color = color_data[tdata["pos"][1]][tdata["pos"][0]]
|
| 221 |
+
if np.dot(color_weight, base_color) > 128:
|
| 222 |
+
text_color = "black"
|
| 223 |
+
else:
|
| 224 |
+
text_color = "white"
|
| 225 |
+
|
| 226 |
+
txposi = (tdata["pos"][0] + 0.5) * dx / dpi
|
| 227 |
+
typosi = (tdata["pos"][1] + 0.5) * dy / dpi
|
| 228 |
+
ax.text(txposi, typosi, tdata["text01"], ha="center", va="center", color=text_color, fontsize=6)
|
| 229 |
+
|
| 230 |
+
## 显示核素名称
|
| 231 |
+
elif text_mode == 2:
|
| 232 |
+
for tdata in text_data:
|
| 233 |
+
## 根据方块颜色选择文本颜色(黑或白)
|
| 234 |
+
base_color = color_data[tdata["pos"][1]][tdata["pos"][0]]
|
| 235 |
+
if np.dot(color_weight, base_color) > 128:
|
| 236 |
+
text_color = "black"
|
| 237 |
+
else:
|
| 238 |
+
text_color = "white"
|
| 239 |
+
|
| 240 |
+
txposi = (tdata["pos"][0] + 0.5) * dx / dpi
|
| 241 |
+
typosi = (tdata["pos"][1] + 0.5) * dy / dpi
|
| 242 |
+
ax.text(txposi, typosi, tdata["text02"], ha="center", va="center", color=text_color, fontsize=6)
|
| 243 |
+
|
| 244 |
+
## 显示详细信息
|
| 245 |
+
elif text_mode == 3:
|
| 246 |
+
for tdata in text_data:
|
| 247 |
+
## 根据方块颜色选择文本颜色(黑或白)
|
| 248 |
+
base_color = color_data[tdata["pos"][1]][tdata["pos"][0]]
|
| 249 |
+
if np.dot(color_weight, base_color) > 128:
|
| 250 |
+
text_color = "black"
|
| 251 |
+
else:
|
| 252 |
+
text_color = "white"
|
| 253 |
+
|
| 254 |
+
txposi = (tdata["pos"][0] + 0.5) * dx / dpi
|
| 255 |
+
typosi = (tdata["pos"][1] + 0.85) * dy / dpi
|
| 256 |
+
text = tdata["text02"] + "\n" + tdata["text03"]
|
| 257 |
+
ax.text(txposi, typosi, text, ha="center", va="top", ma="center", color=text_color, fontsize=2.4)
|
| 258 |
+
|
| 259 |
+
|
| 260 |
+
|
| 261 |
+
#fig.savefig("test.svg", format="svg")
|
| 262 |
+
#fig.savefig("test.png", format="png")
|
| 263 |
+
#plt.show()
|
| 264 |
+
|
| 265 |
+
return fig
|
| 266 |
+
|
| 267 |
+
def nucildesChartPlotPLTColor(color_data, mode, z_min, n_min ,z_max, n_max):
|
| 268 |
+
## 据半衰期上色
|
| 269 |
+
## 默认使用基态数据
|
| 270 |
+
## nndc上的nudat3绘制时若基态无数据则会使用激发态的数据,此处与其不同 比如:137Pm、154Lu、161Ta 等
|
| 271 |
+
if mode == 0:
|
| 272 |
+
## 自NDfilter.nuclidesClassifyHalflife()
|
| 273 |
+
with open(data_NuclidesClassifiedHalflife_path, "r", encoding="utf8") as file:
|
| 274 |
+
data = json.load(file)
|
| 275 |
+
|
| 276 |
+
for row in data:
|
| 277 |
+
if (row["z"] >= z_min and row["z"] <= z_max) and (row["n"] >= n_min and row["n"] <= n_max):
|
| 278 |
+
ypos = row["z"] - z_min
|
| 279 |
+
xpos = row["n"] - n_min
|
| 280 |
+
if row["type"] in colors_halflife:
|
| 281 |
+
color_data[ypos][xpos] = np.array(colors_halflife[row["type"]])
|
| 282 |
+
|
| 283 |
+
## 据衰变模式上色
|
| 284 |
+
elif mode == 1:
|
| 285 |
+
## 自NDfilter.nuclidesClassifyDecayMode()
|
| 286 |
+
with open(data_NuclidesClassifiedDecayModes_path, "r", encoding="utf8") as file:
|
| 287 |
+
data = json.load(file)
|
| 288 |
+
|
| 289 |
+
for row in data:
|
| 290 |
+
if (row["z"] >= z_min and row["z"] <= z_max) and (row["n"] >= n_min and row["n"] <= n_max):
|
| 291 |
+
ypos = row["z"] - z_min
|
| 292 |
+
xpos = row["n"] - n_min
|
| 293 |
+
if row["type"] in colors_DecayModes:
|
| 294 |
+
color_data[ypos][xpos] = np.array(colors_DecayModes[row["type"]])
|
| 295 |
+
elif row["type"] in ("2B-", "β⁻"):
|
| 296 |
+
color_data[ypos][xpos] = np.array(colors_DecayModes["B-"])
|
| 297 |
+
elif row["type"] in ("2P", "3P"):
|
| 298 |
+
color_data[ypos][xpos] = np.array(colors_DecayModes["P"])
|
| 299 |
+
elif row["type"] in ("2N"):
|
| 300 |
+
color_data[ypos][xpos] = np.array(colors_DecayModes["N"])
|
| 301 |
+
else:
|
| 302 |
+
color_data[ypos][xpos] = np.array(colors_DecayModes["UNKNOWN"])
|
| 303 |
+
|
| 304 |
+
## 据合成方法上色
|
| 305 |
+
elif mode == 2:
|
| 306 |
+
with open(data_synthesisMethods_path, "r", encoding="utf8") as file:
|
| 307 |
+
data = json.load(file)
|
| 308 |
+
|
| 309 |
+
for row in data:
|
| 310 |
+
if (row["z"] >= z_min and row["z"] <= z_max) and (row["n"] >= n_min and row["n"] <= n_max):
|
| 311 |
+
ypos = row["z"] - z_min
|
| 312 |
+
xpos = row["n"] - n_min
|
| 313 |
+
if row["type"] in colors_synthesisMethods:
|
| 314 |
+
color_data[ypos][xpos] = np.array(colors_synthesisMethods[row["type"]])
|
| 315 |
+
|
| 316 |
+
return color_data
|
| 317 |
+
|
| 318 |
+
def legendHandlesGet(plot_mode):
|
| 319 |
+
handles = []
|
| 320 |
+
if plot_mode == 0:
|
| 321 |
+
for hl_tag in colors_halflife:
|
| 322 |
+
if hl_tag == "ST":
|
| 323 |
+
pass
|
| 324 |
+
elif hl_tag == "1e15s":
|
| 325 |
+
handles.append(Patch(facecolor=np.array(colors_halflife[hl_tag])/255., label=">1e15s or Stable"))
|
| 326 |
+
else:
|
| 327 |
+
handles.append(Patch(facecolor=np.array(colors_halflife[hl_tag])/255., label=legends_halflife[hl_tag]))
|
| 328 |
+
|
| 329 |
+
elif plot_mode == 1:
|
| 330 |
+
for decay_mode in colors_DecayModes:
|
| 331 |
+
handles.append(Patch(facecolor=np.array(colors_DecayModes[decay_mode])/255., label=legends_DecayModes[decay_mode]))
|
| 332 |
+
|
| 333 |
+
elif plot_mode == 2:
|
| 334 |
+
for synthesis_method in colors_synthesisMethods:
|
| 335 |
+
handles.append(Patch(facecolor=np.array(colors_synthesisMethods[synthesis_method])/255., label=names_synthesisMethods[synthesis_method]))
|
| 336 |
+
|
| 337 |
+
return handles
|
| 338 |
+
|
| 339 |
+
def nucildesChartPlotPLTText(plot_mode, z_min, n_min ,z_max, n_max):
|
| 340 |
+
with open(ElementsList_path, "r", encoding="utf8") as file:
|
| 341 |
+
elements_list = json.load(file)
|
| 342 |
+
|
| 343 |
+
text_data = []
|
| 344 |
+
if plot_mode == 0 or plot_mode == 1:
|
| 345 |
+
with open(nuclides_data_path, "r", encoding="utf8") as file:
|
| 346 |
+
data = json.load(file)
|
| 347 |
+
|
| 348 |
+
## 填充半衰期及衰变模式信息
|
| 349 |
+
## 对于衰变模式多于三种的,只显示其前三种(仿nndc)
|
| 350 |
+
## 对于过长的数字,将会对其进行截断
|
| 351 |
+
for nom, ndata in data.items():
|
| 352 |
+
if (ndata["z"] >= z_min and ndata["z"] <= z_max) and (ndata["n"] >= n_min and ndata["n"] <= n_max):
|
| 353 |
+
ypos = ndata["z"] - z_min
|
| 354 |
+
xpos = ndata["n"] - n_min
|
| 355 |
+
text01 = elements_list[str(ndata["z"])]
|
| 356 |
+
text02 = str(ndata["z"]+ndata["n"]) + text01
|
| 357 |
+
|
| 358 |
+
hlt = ""
|
| 359 |
+
dmst = []
|
| 360 |
+
if len(ndata["levels"]) == 0:
|
| 361 |
+
hlt = ""
|
| 362 |
+
dmst = []
|
| 363 |
+
else:
|
| 364 |
+
if not "halflife" in ndata["levels"][0]:
|
| 365 |
+
hlt = ""
|
| 366 |
+
elif not "value" in ndata["levels"][0]["halflife"]:
|
| 367 |
+
hlt = ""
|
| 368 |
+
elif ndata["levels"][0]["halflife"]["value"] == "STABLE":
|
| 369 |
+
hlt = "STABLE"
|
| 370 |
+
else:
|
| 371 |
+
hlv = ndata["levels"][0]["halflife"]["value"]
|
| 372 |
+
if hlv > 1e4:
|
| 373 |
+
hlt = f"{hlv:.2e}"
|
| 374 |
+
else:
|
| 375 |
+
hlt = str(hlv)
|
| 376 |
+
|
| 377 |
+
if ndata["levels"][0]["halflife"]["unit"] == "m":
|
| 378 |
+
hlt = hlt + " min"
|
| 379 |
+
else:
|
| 380 |
+
hlt = hlt + " " + ndata["levels"][0]["halflife"]["unit"]
|
| 381 |
+
|
| 382 |
+
if not "decayModes" in ndata["levels"][0]:
|
| 383 |
+
dmst = []
|
| 384 |
+
else:
|
| 385 |
+
decay_modes = ndata["levels"][0]["decayModes"]["observed"] + ndata["levels"][0]["decayModes"]["predicted"]
|
| 386 |
+
if len(decay_modes) == 0:
|
| 387 |
+
dmst = []
|
| 388 |
+
else:
|
| 389 |
+
## 据分支比排序
|
| 390 |
+
dms1 = []
|
| 391 |
+
dms2 = []
|
| 392 |
+
dmsd = {}
|
| 393 |
+
dmsd1 = []
|
| 394 |
+
for decay_mode in decay_modes:
|
| 395 |
+
if not "value" in decay_mode:
|
| 396 |
+
dms2.append(decay_mode)
|
| 397 |
+
else:
|
| 398 |
+
dmsd[decay_mode["mode"]] = decay_mode
|
| 399 |
+
dmsd1.append((decay_mode["value"], decay_mode["mode"]))
|
| 400 |
+
dmsdf = pd.DataFrame(dmsd1, columns=["value", "mode"])
|
| 401 |
+
dmsdf.sort_values(by="value", ascending=False, inplace=True)
|
| 402 |
+
for mode in dmsdf["mode"]:
|
| 403 |
+
dms1.append(dmsd[mode])
|
| 404 |
+
dms = dms1 + dms2
|
| 405 |
+
###
|
| 406 |
+
for decay_mode in dms:
|
| 407 |
+
text = decay_mode["mode"]
|
| 408 |
+
if not "value" in decay_mode:
|
| 409 |
+
text = text + " ?"
|
| 410 |
+
else:
|
| 411 |
+
dmv = decay_mode["value"]
|
| 412 |
+
dmt = str(dmv)
|
| 413 |
+
if len(dmt) > 7:
|
| 414 |
+
if re.search(rf"([eE])", dmt) == None:
|
| 415 |
+
if dmv > 1e-3:
|
| 416 |
+
dmt = dmt[:7]
|
| 417 |
+
else:
|
| 418 |
+
match00 = re.fullmatch(rf"(0+)(\.)(0+)([1-9]+)", dmt)
|
| 419 |
+
if not match00 == None:
|
| 420 |
+
ne = match00.group(4)
|
| 421 |
+
if len(ne) < 3:
|
| 422 |
+
dmt = f"{dmv:e}"
|
| 423 |
+
else:
|
| 424 |
+
dmt = f"{dmv:.2e}"
|
| 425 |
+
if decay_mode["uncertainty"]["type"] == "limit":
|
| 426 |
+
if decay_mode["uncertainty"]["limitType"] == "lower":
|
| 427 |
+
if decay_mode["uncertainty"]["isInclusive"] == True:
|
| 428 |
+
text = text + " ≥ " + dmt + "%"
|
| 429 |
+
else:
|
| 430 |
+
text = text + " > " + dmt + "%"
|
| 431 |
+
elif decay_mode["uncertainty"]["limitType"] == "upper":
|
| 432 |
+
if decay_mode["uncertainty"]["isInclusive"] == True:
|
| 433 |
+
text = text + " ≤ " + dmt + "%"
|
| 434 |
+
else:
|
| 435 |
+
text = text + " < " + dmt + "%"
|
| 436 |
+
else:
|
| 437 |
+
text = text + " = " + dmt + "%"
|
| 438 |
+
dmst.append(text)
|
| 439 |
+
text03 = hlt + "\n"
|
| 440 |
+
if not len(dmst) > 0:
|
| 441 |
+
pass
|
| 442 |
+
elif len(dmst) <= 3:
|
| 443 |
+
for dmt in dmst:
|
| 444 |
+
text03 = text03 + "\n" + dmt
|
| 445 |
+
else:
|
| 446 |
+
for idx in range(0, 3):
|
| 447 |
+
text03 = text03 + "\n" + dmst[idx]
|
| 448 |
+
|
| 449 |
+
text_data.append({"pos":(xpos, ypos), "text01":text01, "text02":text02, "text03":text03})
|
| 450 |
+
|
| 451 |
+
## 填充合成方法信息
|
| 452 |
+
elif plot_mode == 2:
|
| 453 |
+
with open(data_synthesisMethods_path, "r", encoding="utf8") as file:
|
| 454 |
+
data = json.load(file)
|
| 455 |
+
|
| 456 |
+
for row in data:
|
| 457 |
+
if (row["z"] >= z_min and row["z"] <= z_max) and (row["n"] >= n_min and row["n"] <= n_max):
|
| 458 |
+
ypos = row["z"] - z_min
|
| 459 |
+
xpos = row["n"] - n_min
|
| 460 |
+
text01 = elements_list[str(row["z"])]
|
| 461 |
+
text02 = str(row["z"]+row["n"]) + text01
|
| 462 |
+
text03 = row["type"]
|
| 463 |
+
text_data.append({"pos":(xpos, ypos), "text01":text01, "text02":text02, "text03":text03})
|
| 464 |
+
|
| 465 |
+
return text_data
|
| 466 |
+
|
| 467 |
+
|
| 468 |
+
## test
|
app.py
CHANGED
|
@@ -1,256 +1,349 @@
|
|
| 1 |
-
import gradio as gr
|
| 2 |
-
import pandas as pd
|
| 3 |
-
import json
|
| 4 |
-
from tempfile import NamedTemporaryFile
|
| 5 |
-
|
| 6 |
-
import NDfilter
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
|
| 19 |
-
|
| 20 |
-
|
| 21 |
-
|
| 22 |
-
|
| 23 |
-
|
| 24 |
-
|
| 25 |
-
|
| 26 |
-
|
| 27 |
-
|
| 28 |
-
|
| 29 |
-
|
| 30 |
-
|
| 31 |
-
|
| 32 |
-
|
| 33 |
-
|
| 34 |
-
|
| 35 |
-
|
| 36 |
-
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
|
| 40 |
-
|
| 41 |
-
|
| 42 |
-
|
| 43 |
-
|
| 44 |
-
|
| 45 |
-
|
| 46 |
-
|
| 47 |
-
|
| 48 |
-
|
| 49 |
-
|
| 50 |
-
|
| 51 |
-
|
| 52 |
-
|
| 53 |
-
|
| 54 |
-
|
| 55 |
-
|
| 56 |
-
|
| 57 |
-
|
| 58 |
-
|
| 59 |
-
|
| 60 |
-
|
| 61 |
-
|
| 62 |
-
|
| 63 |
-
|
| 64 |
-
|
| 65 |
-
if
|
| 66 |
-
|
| 67 |
-
|
| 68 |
-
|
| 69 |
-
|
| 70 |
-
|
| 71 |
-
|
| 72 |
-
|
| 73 |
-
|
| 74 |
-
|
| 75 |
-
|
| 76 |
-
|
| 77 |
-
|
| 78 |
-
|
| 79 |
-
|
| 80 |
-
|
| 81 |
-
tmpDataframe
|
| 82 |
-
|
| 83 |
-
|
| 84 |
-
|
| 85 |
-
|
| 86 |
-
|
| 87 |
-
|
| 88 |
-
|
| 89 |
-
|
| 90 |
-
|
| 91 |
-
|
| 92 |
-
|
| 93 |
-
|
| 94 |
-
|
| 95 |
-
|
| 96 |
-
|
| 97 |
-
|
| 98 |
-
|
| 99 |
-
|
| 100 |
-
|
| 101 |
-
|
| 102 |
-
|
| 103 |
-
|
| 104 |
-
|
| 105 |
-
|
| 106 |
-
|
| 107 |
-
|
| 108 |
-
|
| 109 |
-
|
| 110 |
-
|
| 111 |
-
|
| 112 |
-
|
| 113 |
-
|
| 114 |
-
|
| 115 |
-
|
| 116 |
-
|
| 117 |
-
|
| 118 |
-
|
| 119 |
-
|
| 120 |
-
|
| 121 |
-
|
| 122 |
-
|
| 123 |
-
|
| 124 |
-
|
| 125 |
-
|
| 126 |
-
|
| 127 |
-
|
| 128 |
-
|
| 129 |
-
|
| 130 |
-
|
| 131 |
-
|
| 132 |
-
|
| 133 |
-
|
| 134 |
-
|
| 135 |
-
|
| 136 |
-
|
| 137 |
-
|
| 138 |
-
|
| 139 |
-
|
| 140 |
-
|
| 141 |
-
|
| 142 |
-
|
| 143 |
-
|
| 144 |
-
|
| 145 |
-
|
| 146 |
-
|
| 147 |
-
|
| 148 |
-
|
| 149 |
-
|
| 150 |
-
|
| 151 |
-
|
| 152 |
-
|
| 153 |
-
|
| 154 |
-
|
| 155 |
-
|
| 156 |
-
|
| 157 |
-
|
| 158 |
-
|
| 159 |
-
|
| 160 |
-
|
| 161 |
-
|
| 162 |
-
|
| 163 |
-
|
| 164 |
-
|
| 165 |
-
|
| 166 |
-
|
| 167 |
-
|
| 168 |
-
|
| 169 |
-
|
| 170 |
-
|
| 171 |
-
|
| 172 |
-
|
| 173 |
-
|
| 174 |
-
|
| 175 |
-
|
| 176 |
-
|
| 177 |
-
|
| 178 |
-
|
| 179 |
-
|
| 180 |
-
|
| 181 |
-
|
| 182 |
-
|
| 183 |
-
|
| 184 |
-
|
| 185 |
-
|
| 186 |
-
|
| 187 |
-
|
| 188 |
-
|
| 189 |
-
|
| 190 |
-
|
| 191 |
-
|
| 192 |
-
|
| 193 |
-
|
| 194 |
-
|
| 195 |
-
|
| 196 |
-
|
| 197 |
-
|
| 198 |
-
|
| 199 |
-
|
| 200 |
-
|
| 201 |
-
|
| 202 |
-
|
| 203 |
-
|
| 204 |
-
|
| 205 |
-
|
| 206 |
-
|
| 207 |
-
gr.Markdown("
|
| 208 |
-
|
| 209 |
-
|
| 210 |
-
|
| 211 |
-
|
| 212 |
-
|
| 213 |
-
|
| 214 |
-
|
| 215 |
-
|
| 216 |
-
|
| 217 |
-
|
| 218 |
-
|
| 219 |
-
|
| 220 |
-
|
| 221 |
-
|
| 222 |
-
|
| 223 |
-
|
| 224 |
-
|
| 225 |
-
|
| 226 |
-
|
| 227 |
-
|
| 228 |
-
|
| 229 |
-
|
| 230 |
-
|
| 231 |
-
|
| 232 |
-
|
| 233 |
-
|
| 234 |
-
|
| 235 |
-
|
| 236 |
-
|
| 237 |
-
fn=
|
| 238 |
-
inputs
|
| 239 |
-
|
| 240 |
-
|
| 241 |
-
|
| 242 |
-
|
| 243 |
-
|
| 244 |
-
|
| 245 |
-
|
| 246 |
-
|
| 247 |
-
|
| 248 |
-
|
| 249 |
-
|
| 250 |
-
|
| 251 |
-
""
|
| 252 |
-
|
| 253 |
-
|
| 254 |
-
|
| 255 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 256 |
demo.launch()
|
|
|
|
| 1 |
+
import gradio as gr
|
| 2 |
+
import pandas as pd
|
| 3 |
+
import json
|
| 4 |
+
from tempfile import NamedTemporaryFile
|
| 5 |
+
|
| 6 |
+
import NDfilter
|
| 7 |
+
import NDplot
|
| 8 |
+
|
| 9 |
+
## 核素筛选
|
| 10 |
+
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):
|
| 11 |
+
|
| 12 |
+
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)
|
| 13 |
+
|
| 14 |
+
# 根据母核半衰期进行筛选
|
| 15 |
+
if hl_enable_idx == 1:
|
| 16 |
+
hl_min_sec = HLunit_convert(hl_min, hl_min_unit)
|
| 17 |
+
hl_max_sec = HLunit_convert(hl_max, hl_max_unit)
|
| 18 |
+
filtered_data = NDfilter.nuclidesFilterHalflife(filtered_data, hl_min_sec, hl_max_sec)
|
| 19 |
+
|
| 20 |
+
# 根据衰变模式进行筛选
|
| 21 |
+
if dm_enable_idx > 0 and decay_modes:
|
| 22 |
+
filtered_data = NDfilter.nuclidesFilterDecayModes(filtered_data, dm_enable_idx, decay_modes)
|
| 23 |
+
|
| 24 |
+
# 结果处理
|
| 25 |
+
if len(filtered_data) == 0:
|
| 26 |
+
result_text = "没有找到符合条件的核素"
|
| 27 |
+
result_file_path = None
|
| 28 |
+
else:
|
| 29 |
+
result_text = f"找到 {len(filtered_data)} 个符合条件的核素"
|
| 30 |
+
with NamedTemporaryFile(suffix=".json", delete=False, mode='w') as file:
|
| 31 |
+
json.dump(filtered_data, file, indent=2)
|
| 32 |
+
result_file_path = file.name
|
| 33 |
+
return result_text, result_file_path
|
| 34 |
+
|
| 35 |
+
## 核素查找
|
| 36 |
+
def process_search(mode_idx, nom, z, n, a, preview_mode, file_type):
|
| 37 |
+
result = None
|
| 38 |
+
if mode_idx == 0:
|
| 39 |
+
result = NDfilter.nuclidesSearchingNom(nuclides_data, nom.replace(" ", ""))
|
| 40 |
+
elif mode_idx == 1:
|
| 41 |
+
if not (z == None or n == None):
|
| 42 |
+
result = NDfilter.nuclidesSearchingZN(nuclides_data, z, n)
|
| 43 |
+
elif mode_idx == 2:
|
| 44 |
+
if not (z == None or a == None):
|
| 45 |
+
result = NDfilter.nuclidesSearchingZA(nuclides_data, z, a)
|
| 46 |
+
elif mode_idx == 3:
|
| 47 |
+
if not (n == None or a == None):
|
| 48 |
+
result = NDfilter.nuclidesSearchingNA(nuclides_data, n, a)
|
| 49 |
+
|
| 50 |
+
## 结果处理
|
| 51 |
+
if result == None:
|
| 52 |
+
result_text = "没有找到此核素"
|
| 53 |
+
result_dataframe = None
|
| 54 |
+
result_file_path = None
|
| 55 |
+
else:
|
| 56 |
+
## 文本
|
| 57 |
+
name = result["name"]
|
| 58 |
+
result_text = f"{name}"
|
| 59 |
+
if len(result["levels"]) == 0:
|
| 60 |
+
result_text = result_text + "\n此核素无数据"
|
| 61 |
+
result_text = result_text + "\n\nnndc页面:\n\ngetdataset:\n" + f"https://www.nndc.bnl.gov/nudat3/getdataset.jsp?nucleus={name}&unc=NDS"
|
| 62 |
+
## temp
|
| 63 |
+
with open ("data/haveDecayPage.json",'r', encoding='utf-8') as file:
|
| 64 |
+
haveDecayPage = json.load(file)
|
| 65 |
+
if haveDecayPage[name]:
|
| 66 |
+
result_text = result_text + "\n\ndecaysearchdirect:\n" + f"https://www.nndc.bnl.gov/nudat3/decaysearchdirect.jsp?nuc={name}&unc=NDS"
|
| 67 |
+
|
| 68 |
+
## 预览表格
|
| 69 |
+
if preview_mode == 0:
|
| 70 |
+
result_dataframe = NDfilter.nuclideData_dict2dataframeCompact(result)
|
| 71 |
+
elif preview_mode == 1:
|
| 72 |
+
result_dataframe = NDfilter.nuclideData_dict2dataframe(result)
|
| 73 |
+
|
| 74 |
+
## 文件
|
| 75 |
+
if file_type == 0:
|
| 76 |
+
with NamedTemporaryFile(suffix=".json", delete=False, mode='w') as file:
|
| 77 |
+
json.dump(result, file, indent=2)
|
| 78 |
+
result_file_path = file.name
|
| 79 |
+
elif file_type == 1:
|
| 80 |
+
if preview_mode == 1:
|
| 81 |
+
tmpDataframe = result_dataframe
|
| 82 |
+
else:
|
| 83 |
+
tmpDataframe = NDfilter.nuclideData_dict2dataframe(result)
|
| 84 |
+
with NamedTemporaryFile(suffix=".csv", delete=False, mode='w') as file:
|
| 85 |
+
tmpDataframe.to_csv(file, index=False)
|
| 86 |
+
result_file_path = file.name
|
| 87 |
+
else:
|
| 88 |
+
result_file_path = None
|
| 89 |
+
|
| 90 |
+
return result_text, result_dataframe, result_file_path
|
| 91 |
+
|
| 92 |
+
## 核素图绘制
|
| 93 |
+
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):
|
| 94 |
+
if have_legend_idx == 0:
|
| 95 |
+
have_legend = True
|
| 96 |
+
else:
|
| 97 |
+
have_legend = False
|
| 98 |
+
|
| 99 |
+
area = ((0,0),(118,177))
|
| 100 |
+
if using_filter == 1:
|
| 101 |
+
area = ((Z_min,N_min), (Z_max, N_max))
|
| 102 |
+
|
| 103 |
+
result_fig = NDplot.nucildesChartPlotPLT(plot_mode, area, text_mode, have_legend)
|
| 104 |
+
|
| 105 |
+
with NamedTemporaryFile(suffix=".svg", delete=False, mode='wb') as file:
|
| 106 |
+
result_fig.savefig(file, format="svg")
|
| 107 |
+
preview_svg_path = file.name
|
| 108 |
+
|
| 109 |
+
if file_type3 == "png":
|
| 110 |
+
with NamedTemporaryFile(suffix=".png", delete=False, mode='wb') as file:
|
| 111 |
+
result_fig.savefig(file, format="png")
|
| 112 |
+
result_file_path = file.name
|
| 113 |
+
elif file_type3 == "svg":
|
| 114 |
+
result_file_path = preview_svg_path
|
| 115 |
+
else:
|
| 116 |
+
result_file_path = None
|
| 117 |
+
|
| 118 |
+
return result_fig, result_file_path
|
| 119 |
+
|
| 120 |
+
|
| 121 |
+
## 半衰期单位转换
|
| 122 |
+
def HLunit_convert(hl, hl_unit):
|
| 123 |
+
if hl_unit == "Stable":
|
| 124 |
+
hl_sec = None
|
| 125 |
+
else:
|
| 126 |
+
hl_sec = hl * HL_UNITS[hl_unit]
|
| 127 |
+
return hl_sec
|
| 128 |
+
|
| 129 |
+
## 处理查找页面输入组件激活情况
|
| 130 |
+
def update_inputs2(mode_idx):
|
| 131 |
+
|
| 132 |
+
if mode_idx == 0: # 核素名称模式
|
| 133 |
+
return [gr.Textbox(interactive=True), gr.Number(interactive=False, value=None), gr.Number(interactive=False, value=None), gr.Number(interactive=False, value=None)]
|
| 134 |
+
elif mode_idx == 1: # Z+N模式
|
| 135 |
+
return [gr.Textbox(interactive=False, value=None), gr.Number(interactive=True), gr.Number(interactive=True), gr.Number(interactive=False, value=None)]
|
| 136 |
+
elif mode_idx == 2: # Z+A模式
|
| 137 |
+
return [gr.Textbox(interactive=False, value=None), gr.Number(interactive=True), gr.Number(interactive=False, value=None), gr.Number(interactive=True)]
|
| 138 |
+
elif mode_idx == 3: # N+A模式
|
| 139 |
+
return [gr.Textbox(interactive=False, value=None), gr.Number(interactive=False, value=None), gr.Number(interactive=True), gr.Number(interactive=True)]
|
| 140 |
+
else:
|
| 141 |
+
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)]
|
| 142 |
+
|
| 143 |
+
|
| 144 |
+
def update_inputs3(using_filter):
|
| 145 |
+
if using_filter == 0:
|
| 146 |
+
return [gr.Number(interactive=False, value=None)] * 4
|
| 147 |
+
elif using_filter == 1:
|
| 148 |
+
return [gr.Number(interactive=True)] * 4
|
| 149 |
+
else:
|
| 150 |
+
return [gr.Number(interactive=False, value=None)] * 4
|
| 151 |
+
|
| 152 |
+
## 导入数据集
|
| 153 |
+
nuclides_data_path = "data/nndc_nudat_data_export.json"
|
| 154 |
+
with open (nuclides_data_path,'r', encoding='utf-8') as file:
|
| 155 |
+
nuclides_data = json.load(file)
|
| 156 |
+
|
| 157 |
+
## 半衰期单位转换字典
|
| 158 |
+
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}
|
| 159 |
+
|
| 160 |
+
with gr.Blocks(title="核数据工具") as demo:
|
| 161 |
+
gr.Markdown("""
|
| 162 |
+
## 核数据工具
|
| 163 |
+
可能是用来处理核数据的相关工具??
|
| 164 |
+
|
| 165 |
+
目前功能有:核素筛选、核素查找、核素图绘制。
|
| 166 |
+
""")
|
| 167 |
+
|
| 168 |
+
with gr.Tab("核素筛选"):
|
| 169 |
+
gr.Markdown("""
|
| 170 |
+
## 核素筛选
|
| 171 |
+
可以通过质子数(Z)、中子数(N)、质量数(A)以及母核半衰期、衰变模式等进行筛选
|
| 172 |
+
""")
|
| 173 |
+
with gr.Row():
|
| 174 |
+
with gr.Column(scale=1):
|
| 175 |
+
gr.Markdown("根据质子数(Z)、中子数(N)、质量数(A)进行筛选")
|
| 176 |
+
with gr.Column(scale=4):
|
| 177 |
+
with gr.Row():
|
| 178 |
+
with gr.Column(min_width=240):
|
| 179 |
+
gr.Markdown("质子数(Z)")
|
| 180 |
+
Z_min = gr.Number(label="最小值", precision=0)
|
| 181 |
+
Z_max = gr.Number(label="最大值", precision=0)
|
| 182 |
+
Z_oe = gr.Dropdown(["任意", "奇Z", "偶Z"], label="奇偶", type="index", interactive=True)
|
| 183 |
+
with gr.Column(min_width=240):
|
| 184 |
+
gr.Markdown("中子数(N)")
|
| 185 |
+
N_min = gr.Number(label="最小值", precision=0)
|
| 186 |
+
N_max = gr.Number(label="最大值", precision=0)
|
| 187 |
+
N_oe = gr.Dropdown(["任意", "奇N", "偶N"], label="奇偶", type="index", interactive=True)
|
| 188 |
+
with gr.Column(min_width=240):
|
| 189 |
+
gr.Markdown("质量数(A)")
|
| 190 |
+
A_min = gr.Number(label="最小值", precision=0)
|
| 191 |
+
A_max = gr.Number(label="最大值", precision=0)
|
| 192 |
+
A_oe = gr.Dropdown(["任意", "奇A", "偶A"], label="奇偶", type="index", interactive=True)
|
| 193 |
+
|
| 194 |
+
with gr.Row():
|
| 195 |
+
with gr.Column(scale=1):
|
| 196 |
+
gr.Markdown("根据母核半衰期进行筛选")
|
| 197 |
+
with gr.Column(scale=4):
|
| 198 |
+
with gr.Row():
|
| 199 |
+
hl_enable = gr.Radio(["不使用", "使用"], value="不使用", type="index", show_label=False)
|
| 200 |
+
hl_min = gr.Number(label="最小值", minimum=0.)
|
| 201 |
+
hl_min_unit = gr.Dropdown(["fs", "ps", "ns", "us", "ms", "s", "m", "h", "d", "y", "ky", "My", "Gy", "Stable"], value="fs", interactive=True)
|
| 202 |
+
hl_max = gr.Number(label="最大值", minimum=0.)
|
| 203 |
+
hl_max_unit = gr.Dropdown(["fs", "ps", "ns", "us", "ms", "s", "m", "h", "d", "y", "ky", "My", "Gy", "Stable"], value="Stable", interactive=True)
|
| 204 |
+
|
| 205 |
+
with gr.Row():
|
| 206 |
+
with gr.Column(scale=1):
|
| 207 |
+
gr.Markdown("根据衰变模式进行筛选")
|
| 208 |
+
with gr.Column(scale=4):
|
| 209 |
+
with gr.Row():
|
| 210 |
+
dm_enable_idx = gr.Radio(["不使用", "筛选包含所有以下所选衰变模式的核素(and)", "筛选包含任意以下所选衰变模式的核素(or)"], value="不使用", type="index", interactive=True, show_label=False)
|
| 211 |
+
with gr.Row():
|
| 212 |
+
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="decayModes", interactive=True)
|
| 213 |
+
|
| 214 |
+
with gr.Row():
|
| 215 |
+
submit_btn = gr.Button("筛选", variant="primary")
|
| 216 |
+
reset_btn = gr.Button("重置条件", variant="primary")
|
| 217 |
+
|
| 218 |
+
with gr.Row():
|
| 219 |
+
result_text = gr.Textbox(label="筛选结果", interactive=False, show_copy_button=True)
|
| 220 |
+
result_file = gr.File(label="结果文件", interactive=False)
|
| 221 |
+
|
| 222 |
+
inputs = [
|
| 223 |
+
Z_min, Z_max, Z_oe,
|
| 224 |
+
N_min, N_max, N_oe,
|
| 225 |
+
A_min, A_max, A_oe,
|
| 226 |
+
hl_enable, hl_min, hl_min_unit, hl_max, hl_max_unit,
|
| 227 |
+
dm_enable_idx, decayModes
|
| 228 |
+
]
|
| 229 |
+
|
| 230 |
+
submit_btn.click(
|
| 231 |
+
fn=process_filters,
|
| 232 |
+
inputs=inputs,
|
| 233 |
+
outputs=[result_text, result_file]
|
| 234 |
+
)
|
| 235 |
+
|
| 236 |
+
reset_btn.click(
|
| 237 |
+
fn=lambda: [None,None,"任意"]*3 + ["不使用", None, "fs", None, "Stable"] + ["不使用", []],
|
| 238 |
+
outputs=inputs
|
| 239 |
+
)
|
| 240 |
+
|
| 241 |
+
|
| 242 |
+
with gr.Tab("核素查找"):
|
| 243 |
+
gr.Markdown("## 核素查找")
|
| 244 |
+
with gr.Row():
|
| 245 |
+
with gr.Column(scale=3):
|
| 246 |
+
searchingMode = gr.Radio(["核素名称", "质子数(Z)、中子数(N)", "质子数(Z)、质量数(A)", "中子数(N)、质量数(A)"], value="核素名称", label="查找模式", interactive=True, type="index")
|
| 247 |
+
gr.Markdown("### 根据核素名称查找")
|
| 248 |
+
nuclide_in = gr.Textbox(value=None, info="请输入由质量数及元素名称所组成的核素名称,示例:232Th、232TH、th232、232-Th、th-232等。\n只要不太离谱就能识别……大概?")
|
| 249 |
+
gr.Markdown("### 根据质子数(Z)、中子数(N)、质量数(A)查找")
|
| 250 |
+
with gr.Row():
|
| 251 |
+
Z_in = gr.Number(value=0, label="质子数(Z)", precision=0, interactive=False)
|
| 252 |
+
N_in = gr.Number(value=0, label="中子数(N)", precision=0, interactive=False)
|
| 253 |
+
A_in = gr.Number(value=0, label="质量数(A)", precision=0, interactive=False)
|
| 254 |
+
previewMode = gr.Radio(["紧凑", "常规"], value="紧凑", type="index", label="预览模式")
|
| 255 |
+
outputFileType = gr.Radio(["json", "csv"], value="json", type="index", label="导出文件格式")
|
| 256 |
+
with gr.Row():
|
| 257 |
+
submit_btn2 = gr.Button("查找", variant="primary")
|
| 258 |
+
reset_btn2 = gr.Button("重置条件", variant="primary")
|
| 259 |
+
|
| 260 |
+
with gr.Column(scale=2):
|
| 261 |
+
result_text2 = gr.Textbox(interactive=False, show_label=False)
|
| 262 |
+
preview_df = gr.Dataframe(label="数据预览", interactive=False)
|
| 263 |
+
result_file2 = gr.File(interactive=False)
|
| 264 |
+
|
| 265 |
+
searchingMode.change(
|
| 266 |
+
fn=update_inputs2,
|
| 267 |
+
inputs=searchingMode,
|
| 268 |
+
outputs=[nuclide_in, Z_in, N_in, A_in]
|
| 269 |
+
)
|
| 270 |
+
|
| 271 |
+
inputs2 = [
|
| 272 |
+
searchingMode,
|
| 273 |
+
nuclide_in,
|
| 274 |
+
Z_in, N_in, A_in,
|
| 275 |
+
previewMode, outputFileType
|
| 276 |
+
]
|
| 277 |
+
|
| 278 |
+
submit_btn2.click(
|
| 279 |
+
fn=process_search,
|
| 280 |
+
inputs=inputs2,
|
| 281 |
+
outputs=[result_text2, preview_df, result_file2]
|
| 282 |
+
)
|
| 283 |
+
|
| 284 |
+
reset_btn2.click(
|
| 285 |
+
fn=lambda: [None]*4,
|
| 286 |
+
outputs=[nuclide_in, Z_in, N_in, A_in]
|
| 287 |
+
)
|
| 288 |
+
|
| 289 |
+
with gr.Tab("核素图绘制"):
|
| 290 |
+
gr.Markdown("""
|
| 291 |
+
## 核素图绘制
|
| 292 |
+
|
| 293 |
+
可根据半衰期、衰变模式、合成方法等分类模式绘制核素图。
|
| 294 |
+
|
| 295 |
+
部分代码参考了Ming-Hao-Zhang的[Nuclei-Chart-Generator](https://github.com/Ming-Hao-Zhang/Nuclei-Chart-Generator)
|
| 296 |
+
""")
|
| 297 |
+
with gr.Row():
|
| 298 |
+
with gr.Column(scale=3):
|
| 299 |
+
img_preview = gr.Plot(label="图片预览")
|
| 300 |
+
with gr.Column(scale=2):
|
| 301 |
+
plot_mode = gr.Radio(["寿命", "衰变模式", "合成方法"], value="寿命", label="核素分类模式", type="index")
|
| 302 |
+
text_mode = gr.Radio(["无", "元素名称", "核素名称", "详细信息"], value="无", label="显示信息", type="index")
|
| 303 |
+
have_legend_idx = gr.Radio(["显示图例", "隐藏图例"], value="显示图例", label="图例", type="index")
|
| 304 |
+
file_type3 = gr.Radio(["svg", "png"], value="svg", label="导出格式", info="png为位图格式,svg为矢量图格式。\n显示详细信息时,受分辨率限制,png格式将会失真。如需高清晰度图像,请使用svg。")
|
| 305 |
+
|
| 306 |
+
with gr.Accordion(open=False, label="更多选项") as filter3:
|
| 307 |
+
gr.Markdown("根据质子数(Z)、中子数(N)筛选 (未启用)")
|
| 308 |
+
using_filter = gr.Radio(["不使用", "使用"], value="不使用", show_label=False, type='index', interactive=False)
|
| 309 |
+
with gr.Row():
|
| 310 |
+
with gr.Column(min_width=120):
|
| 311 |
+
gr.Markdown("质子数(Z)")
|
| 312 |
+
Z_min = gr.Number(label="最小值", precision=0, interactive=False)
|
| 313 |
+
Z_max = gr.Number(label="最大值", precision=0, interactive=False)
|
| 314 |
+
with gr.Column(min_width=120):
|
| 315 |
+
gr.Markdown("中子数(N)")
|
| 316 |
+
N_min = gr.Number(label="最小值", precision=0, interactive=False)
|
| 317 |
+
N_max = gr.Number(label="最大值", precision=0, interactive=False)
|
| 318 |
+
|
| 319 |
+
with gr.Row():
|
| 320 |
+
submit_btn3 = gr.Button("绘制", variant="primary")
|
| 321 |
+
reset_btn3 = gr.Button("重置条件", variant="primary")
|
| 322 |
+
|
| 323 |
+
result_file3 = gr.File(interactive=False)
|
| 324 |
+
|
| 325 |
+
using_filter.change(
|
| 326 |
+
fn=update_inputs3,
|
| 327 |
+
inputs=using_filter,
|
| 328 |
+
outputs=[Z_min, Z_max, N_min, N_max]
|
| 329 |
+
)
|
| 330 |
+
|
| 331 |
+
filter3.collapse(
|
| 332 |
+
fn=lambda: "不使用",
|
| 333 |
+
outputs= using_filter
|
| 334 |
+
)
|
| 335 |
+
|
| 336 |
+
inputs3 = [plot_mode, text_mode, have_legend_idx, file_type3, using_filter, Z_min, Z_max, N_min, N_max]
|
| 337 |
+
|
| 338 |
+
submit_btn3.click(
|
| 339 |
+
fn=process_plot,
|
| 340 |
+
inputs=inputs3,
|
| 341 |
+
outputs=[img_preview, result_file3]
|
| 342 |
+
)
|
| 343 |
+
|
| 344 |
+
reset_btn3.click(
|
| 345 |
+
fn=lambda: ["寿命", "无", "显示图例", "svg", "不使用"] + [None]*4,
|
| 346 |
+
outputs=inputs3
|
| 347 |
+
)
|
| 348 |
+
|
| 349 |
demo.launch()
|
data/ElementsList.json
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"0": "n", "1": "H", "2": "He", "3": "Li", "4": "Be", "5": "B", "6": "C", "7": "N", "8": "O", "9": "F", "10": "Ne", "11": "Na", "12": "Mg", "13": "Al", "14": "Si", "15": "P", "16": "S", "17": "Cl", "18": "Ar", "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", "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", "55": "Cs", "56": "Ba", "57": "La", "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", "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", "87": "Fr", "88": "Ra", "89": "Ac", "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", "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"}
|
data/NuclidesClassifiedDecayModes.json
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
data/NuclidesClassifiedHalflife.json
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
data/Nuclides_synthesisMethods.json
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|