From b0d329164aea8eabbb6b167d3fabf20f4897a80d Mon Sep 17 00:00:00 2001 From: "Ryan@SOLARIS_testStation" Date: Mon, 4 Nov 2024 18:26:53 -0500 Subject: [PATCH] plane to add IAEA data and use that to plot Ex level --- .gitignore | 2 +- PyGUIQt6/IAEANuclearData.py | 190 ++++++++++++++++++++++++++++++++++++ PyGUIQt6/README.md | 25 ++++- PyGUIQt6/requirements.txt | 6 ++ PyGUIQt6/test.py | 7 ++ 5 files changed, 228 insertions(+), 2 deletions(-) create mode 100644 PyGUIQt6/IAEANuclearData.py create mode 100644 PyGUIQt6/requirements.txt create mode 100755 PyGUIQt6/test.py diff --git a/.gitignore b/.gitignore index 3645a4f..510085e 100644 --- a/.gitignore +++ b/.gitignore @@ -6,4 +6,4 @@ Cleopatra/InFileCreator Cleopatra/Isotope Cleopatra/PlotTGraphTObjArray -__pycache__ \ No newline at end of file +__pycache__ diff --git a/PyGUIQt6/IAEANuclearData.py b/PyGUIQt6/IAEANuclearData.py new file mode 100644 index 0000000..730aa9b --- /dev/null +++ b/PyGUIQt6/IAEANuclearData.py @@ -0,0 +1,190 @@ +#!/usr/bin/python3 + +import pandas as pd +import urllib.request +import re +import numpy + +me = 0.51099895000 # +- 15 +mp = 938.27208816 # +- 29 +mn = 939.56542052 # +- 54 +ma = 3727.37915 + +class Isotope: + def __int__(self): + + self.livechart = "https://nds.iaea.org/relnsd/v0/data?" + self.data = None + + # Read the saved CSV file back into a DataFrame + try : + self.data = pd.read_csv('IAEA_NuclearData.csv') + except FileNotFoundError: + # the service URL + url = self.livechart + "fields=ground_states&nuclides=all" + self.data = self.lc_read_csv(url) + self.data.insert(0, 'A', self.data['z'] + self.data['n']) + self.data.to_csv('IAEA_NuclearData.csv', index=False) + self.data = pd.read_csv('IAEA_NuclearData.csv') + + def lc_read_csv(self, url): + req = urllib.request.Request(url) + req.add_header('User-Agent', 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:77.0) Gecko/20100101 Firefox/77.0') + return pd.read_csv(urllib.request.urlopen(req)) + + + # print(haha.columns) + ## ['A', 'z', 'n', 'symbol', 'radius', 'unc_r', 'abundance', 'unc_a', + ## 'energy_shift', 'energy', 'unc_e', 'ripl_shift', 'jp', 'half_life', + ## 'operator_hl', 'unc_hl', 'unit_hl', 'half_life_sec', 'unc_hls', + ## 'decay_1', 'decay_1_%', 'unc_1', 'decay_2', 'decay_2_%', 'unc_2', + ## 'decay_3', 'decay_3_%', 'unc_3', 'isospin', 'magnetic_dipole', 'unc_md', + ## 'electric_quadrupole', 'unc_eq', 'qbm', 'unc_qb', 'qbm_n', 'unc_qbmn', + ## 'qa', 'unc_qa', 'qec', 'unc_qec', 'sn', 'unc_sn', 'sp', 'unc_sp', + ## 'binding', 'unc_ba', 'atomic_mass', 'unc_am', 'massexcess', 'unc_me', + ## 'me_systematics', 'discovery', 'ENSDFpublicationcut-off', + ## 'ENSDFauthors', 'Extraction_date'] + + + def GetExList(self, ASym : str, maxEx : float): + try: + exList = self.lc_read_csv(self.livechart + "fields=levels&nuclides=" + ASym) + exJpi = exList[['energy', 'jp']] + exJpi = exJpi[exJpi['energy'] < (maxEx * 1000)] + return exJpi + except: + return pd.DataFrame() + + def BreakDownName(self, ASym : str): + match = re.match(r'(\d+)(\D+)', ASym) + return [int(match.group(1)), match.group(2) ] + + def GetAZ(self, ASym : str): + [A, sym] = self.BreakDownName(ASym) + try: + dudu = self.data[(self.data['symbol']==sym) & (self.data['A']==A)] + Z = int(dudu['z'].iloc[0]) + return [A, Z] + except: + return [A, numpy.nan] + + def GetBindingPerA(self, ASym : str) -> float: + [A, sym] = self.BreakDownName(ASym) + try: + dudu = self.data[(self.data['symbol']==sym) & (self.data['A']==A)] + Z = int(dudu['z'].iloc[0]) + N = A - Z + return dudu['binding'].iloc[0]/1000 + except: + return numpy.nan + + def GetMassFromSym(self, ASym : str) -> float: + [A, sym] = self.BreakDownName(ASym) + try: + dudu = self.data[(self.data['symbol']==sym) & (self.data['A']==A)] + Z = int(dudu['z'].iloc[0]) + N = A - Z + binding = dudu['binding'].iloc[0]/1000 + return Z*mp + N*mn - binding*A + except: + return numpy.nan + + def GetMassFromAZ(self, A : int, Z : int) -> float: + try: + dudu = self.data[(self.data['z']==Z) & (self.data['A']==A)] + Z = int(dudu['z'].iloc[0]) + N = A - Z + binding = dudu['binding'].iloc[0]/1000 + return Z*mp + N*mn - binding*A + except: + return numpy.nan + + def GetSymbol(self, A : int, Z : int) -> str: + try: + dudu = self.data[(self.data['z']==Z) & (self.data['A']==A)] + return "%d%s" % (A , dudu['symbol'].iloc[0]) + except: + return "0x" + + def GetJpi(self, ASym : str): + [A, sym] = self.BreakDownName(ASym) + try: + dudu = self.data[(self.data['symbol']==sym) & (self.data['A']==A)] + return dudu['jp'].iloc[0] + except: + return "unknown" + + def GetHalfLife(self, ASym : str) -> float: + [A, sym] = self.BreakDownName(ASym) + try: + dudu = self.data[(self.data['symbol']==sym) & (self.data['A']==A)] + return dudu['half_life_sec'].iloc[0] + except: + return "unknown" + + def GetSn(self, ASym : str) -> float: + [A, Z] = self.GetAZ(ASym) + if numpy.isnan(Z) : + return numpy.nan + else: + mass0 = self.GetMassFromAZ(A, Z) + mass1 = self.GetMassFromAZ(A-1, Z) + return mass1 + mn - mass0 + + def GetSp(self, ASym : str): + [A, Z] = self.GetAZ(ASym) + if numpy.isnan(Z) : + return numpy.nan + else: + mass0 = self.GetMassFromAZ(A, Z) + mass1 = self.GetMassFromAZ(A-1, Z-1) + return mass1 + mp - mass0 + + def GetSa(self, ASym : str): + [A, Z] = self.GetAZ(ASym) + if numpy.isnan(Z) : + return numpy.nan + else: + mass0 = self.GetMassFromAZ(A, Z) + mass1 = self.GetMassFromAZ(A-4, Z-2) + return mass1 + ma - mass0 + + def PrintIso(self, ASym: str): + [A, Z] = self.GetAZ(ASym) + print("========================= ", ASym) + print("A : %d, Z : %d, N : %d" % (A, Z, A-Z)) + print(" Jpi : ", self.GetJpi(ASym)) + print("half-live : %.2f sec" % (self.GetHalfLife(ASym))) + print(" Mass : %9.2f MeV" % (self.GetMassFromSym(ASym) )) + print(" Binding : %9.2f MeV/A" % (self.GetBindingPerA(ASym))) + print(" Binding : %9.2f MeV" % (self.GetBindingPerA(ASym) * A)) + print(" Sn: %9.2f MeV" % self.GetSn(ASym)) + print(" Sp: %9.2f MeV" % self.GetSp(ASym)) + print(" Sa: %9.2f MeV" % self.GetSa(ASym)) + print("=============================") + + def PrintIsoWeb(self, ASym : str): + [A, Z] = self.GetAZ(ASym) + print("
========================= ", ASym) + print("
A : %d, Z : %d, N : %d" % (A, Z, A-Z)) + print("
Jpi : ", self.GetJpi(ASym)) + print("
half-live : %.2f sec" % (self.GetHalfLife(ASym))) + print("
Mass : %9.2f MeV" % (self.GetMassFromSym(ASym) )) + print("
Binding : %9.2f MeV/A" % (self.GetBindingPerA(ASym))) + print("
Binding : %9.2f MeV" % (self.GetBindingPerA(ASym) * A)) + print("
Sn: %9.2f MeV" % self.GetSn(ASym)) + print("
Sp: %9.2f MeV" % self.GetSp(ASym)) + print("
Sa: %9.2f MeV" % self.GetSa(ASym)) + print("
=============================") + + + def PrintIsoExWeb(self, ASym : str, maxEx : float): + exList = self.GetExList(ASym, maxEx) + if exList.empty: + print("
cannot find Ex data") + else: + print("") + for i in range(0,len(exList)): + print("" % (exList['energy'].iloc[i]/1000, exList['jp'].iloc[i].replace(' ', ','))) + print("
%9.3f%s
") + diff --git a/PyGUIQt6/README.md b/PyGUIQt6/README.md index f1dbbc7..d6dfc34 100644 --- a/PyGUIQt6/README.md +++ b/PyGUIQt6/README.md @@ -1,3 +1,26 @@ +# Force install as system packages -~>python3 -m pip install PyQt6 PyQt6-WebEngine Plotly \ No newline at end of file +Do it as your own risk. If you have other pyQt project, I highly NOT recommand. + + >python3 -m pip install --break-system-package PyQt6 PyQt6-WebEngine Plotly + +# Use Python Virtual Enviroment + +To enable virtual enviroment + >sudo apt install python3.12-venv + +create an virtual enivriment with name ptolemyGUI + >python3 -m venv ptolemyGUI + +To activate the virtual enviroment + >source ptolemyGUI/bin/activate + +To install the packages + >pip install -r requirements.txt + +To deactivate the virtual enviroment + >deactivate + +To remove the virtual enviroment, simply remove the folder + >rm -rf ptolemyGUI \ No newline at end of file diff --git a/PyGUIQt6/requirements.txt b/PyGUIQt6/requirements.txt new file mode 100644 index 0000000..2cc5588 --- /dev/null +++ b/PyGUIQt6/requirements.txt @@ -0,0 +1,6 @@ +plotly +PyQt6 +PyQt6-Qt6 +PyQt6-WebEngine +numpy +pandas diff --git a/PyGUIQt6/test.py b/PyGUIQt6/test.py new file mode 100755 index 0000000..82aade1 --- /dev/null +++ b/PyGUIQt6/test.py @@ -0,0 +1,7 @@ +#!/usr/bin/python3 + +from IAEANuclearData import Isotope + +iso = Isotope() + +iso.PrintIso('16O') \ No newline at end of file