pyphyschemtools 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pyphyschemtools/Chem3D.py +831 -0
- pyphyschemtools/ML.py +42 -0
- pyphyschemtools/PeriodicTable.py +289 -0
- pyphyschemtools/__init__.py +43 -0
- pyphyschemtools/aithermo.py +350 -0
- pyphyschemtools/cheminformatics.py +230 -0
- pyphyschemtools/core.py +119 -0
- pyphyschemtools/icons-logos-banner/Logo_pyPhysChem_border.svg +1109 -0
- pyphyschemtools/icons-logos-banner/__init__.py +0 -0
- pyphyschemtools/icons-logos-banner/logo.png +0 -0
- pyphyschemtools/icons-logos-banner/tools4pyPC_banner.png +0 -0
- pyphyschemtools/icons-logos-banner/tools4pyPC_banner.svg +193 -0
- pyphyschemtools/kinetics.py +193 -0
- pyphyschemtools/resources/css/BrainHalfHalf-120x139.base64 +1 -0
- pyphyschemtools/resources/css/BrainHalfHalf-120x139.png +0 -0
- pyphyschemtools/resources/css/BrainHalfHalf.base64 +8231 -0
- pyphyschemtools/resources/css/BrainHalfHalf.png +0 -0
- pyphyschemtools/resources/css/BrainHalfHalf.svg +289 -0
- pyphyschemtools/resources/css/visualID.css +325 -0
- pyphyschemtools/resources/img/Tranformative_3.webp +0 -0
- pyphyschemtools/resources/img/Tranformative_3_banner.png +0 -0
- pyphyschemtools/resources/img/pyPhysChem_1.png +0 -0
- pyphyschemtools/resources/svg/BrainHalfHalf.png +0 -0
- pyphyschemtools/resources/svg/BrainHalfHalf.svg +289 -0
- pyphyschemtools/resources/svg/GitHub-Logo-C.png +0 -0
- pyphyschemtools/resources/svg/GitHub-Logo.png +0 -0
- pyphyschemtools/resources/svg/Logo-Universite-Toulouse-n-2023.png +0 -0
- pyphyschemtools/resources/svg/Logo_pyPhysChem_1-translucentBgd-woName.png +0 -0
- pyphyschemtools/resources/svg/Logo_pyPhysChem_1-translucentBgd.png +0 -0
- pyphyschemtools/resources/svg/Logo_pyPhysChem_1.png +0 -0
- pyphyschemtools/resources/svg/Logo_pyPhysChem_1.svg +622 -0
- pyphyschemtools/resources/svg/Logo_pyPhysChem_5.png +0 -0
- pyphyschemtools/resources/svg/Logo_pyPhysChem_5.svg +48 -0
- pyphyschemtools/resources/svg/Logo_pyPhysChem_border.svg +1109 -0
- pyphyschemtools/resources/svg/Python-logo-notext.svg +265 -0
- pyphyschemtools/resources/svg/Python_logo_and_wordmark.svg.png +0 -0
- pyphyschemtools/resources/svg/UT3_logoQ.jpg +0 -0
- pyphyschemtools/resources/svg/UT3_logoQ.png +0 -0
- pyphyschemtools/resources/svg/Universite-Toulouse-n-2023.svg +141 -0
- pyphyschemtools/resources/svg/X.png +0 -0
- pyphyschemtools/resources/svg/logoAnaconda.png +0 -0
- pyphyschemtools/resources/svg/logoAnaconda.webp +0 -0
- pyphyschemtools/resources/svg/logoCNRS.png +0 -0
- pyphyschemtools/resources/svg/logoDebut.svg +316 -0
- pyphyschemtools/resources/svg/logoEnd.svg +172 -0
- pyphyschemtools/resources/svg/logoFin.svg +172 -0
- pyphyschemtools/resources/svg/logoPPCL.svg +359 -0
- pyphyschemtools/resources/svg/logoPytChem.png +0 -0
- pyphyschemtools/resources/svg/logo_lpcno_300_dpi_notexttransparent.png +0 -0
- pyphyschemtools/resources/svg/logo_pyPhysChem.png +0 -0
- pyphyschemtools/resources/svg/logo_pyPhysChem_0.png +0 -0
- pyphyschemtools/resources/svg/logo_pyPhysChem_0.svg +390 -0
- pyphyschemtools/resources/svg/logopyPhyschem.png +0 -0
- pyphyschemtools/resources/svg/logopyPhyschem_2.webp +0 -0
- pyphyschemtools/resources/svg/logopyPhyschem_3.webp +0 -0
- pyphyschemtools/resources/svg/logopyPhyschem_4.webp +0 -0
- pyphyschemtools/resources/svg/logopyPhyschem_5.png +0 -0
- pyphyschemtools/resources/svg/logopyPhyschem_5.webp +0 -0
- pyphyschemtools/resources/svg/logopyPhyschem_6.webp +0 -0
- pyphyschemtools/resources/svg/logopyPhyschem_7.webp +0 -0
- pyphyschemtools/resources/svg/logos-Anaconda-pyPhysChem.png +0 -0
- pyphyschemtools/resources/svg/logos-Anaconda-pyPhysChem.svg +58 -0
- pyphyschemtools/resources/svg/pyPCBanner.svg +309 -0
- pyphyschemtools/resources/svg/pyPhysChem-GitHubSocialMediaTemplate.png +0 -0
- pyphyschemtools/resources/svg/pyPhysChem-GitHubSocialMediaTemplate.svg +295 -0
- pyphyschemtools/resources/svg/pyPhysChemBanner.png +0 -0
- pyphyschemtools/resources/svg/pyPhysChemBanner.svg +639 -0
- pyphyschemtools/resources/svg/qrcode-pyPhysChem.png +0 -0
- pyphyschemtools/resources/svg/repository-open-graph-template.png +0 -0
- pyphyschemtools/spectra.py +451 -0
- pyphyschemtools/survey.py +1048 -0
- pyphyschemtools/sympyUtilities.py +51 -0
- pyphyschemtools/tools4AS.py +960 -0
- pyphyschemtools/visualID.py +101 -0
- pyphyschemtools/visualID_Eng.py +175 -0
- pyphyschemtools-0.1.0.dist-info/METADATA +38 -0
- pyphyschemtools-0.1.0.dist-info/RECORD +80 -0
- pyphyschemtools-0.1.0.dist-info/WHEEL +5 -0
- pyphyschemtools-0.1.0.dist-info/licenses/LICENSE +674 -0
- pyphyschemtools-0.1.0.dist-info/top_level.txt +1 -0
pyphyschemtools/ML.py
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
############################################################
|
|
2
|
+
# Machine Learning
|
|
3
|
+
############################################################
|
|
4
|
+
from .visualID_Eng import fg, bg, hl
|
|
5
|
+
from .core import centerTitle, centertxt
|
|
6
|
+
|
|
7
|
+
def y2c(mc2i,y):
|
|
8
|
+
import tensorflow as tf
|
|
9
|
+
from tensorflow import keras
|
|
10
|
+
#from keras.utils import np_utils
|
|
11
|
+
from keras.utils import to_categorical
|
|
12
|
+
y_array = y.copy()
|
|
13
|
+
y_array = y_array.to_numpy() # transformation au format numpy
|
|
14
|
+
# transformation des valeurs de y1 & y2 en entiers
|
|
15
|
+
for x in range(len(y_array)):
|
|
16
|
+
#print(x, y_array[x], mapc2i[y_array[x]])
|
|
17
|
+
y_array[x] = mc2i[y_array[x]]
|
|
18
|
+
yohe = to_categorical(y_array)
|
|
19
|
+
del y_array
|
|
20
|
+
return yohe
|
|
21
|
+
|
|
22
|
+
def categorizeY_2ohe(Ctot, y1, y2):
|
|
23
|
+
"""
|
|
24
|
+
one-hot-encodes a pandas column of categorical data
|
|
25
|
+
input:
|
|
26
|
+
- Ctot is the reference pandas column, necessary to find all unique categories in this column
|
|
27
|
+
- y1 and y2 are the actual pandas column that will be categorized. y1 and y2 are supposed to be the ytest and ytrain subsets of Ctot
|
|
28
|
+
output:
|
|
29
|
+
- y1ohe and y2ohe are the numpy arrays returned by this routine
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
uv = Ctot.unique()
|
|
33
|
+
print(f"Catégories uniques : {uv}")
|
|
34
|
+
mapc2i = {}
|
|
35
|
+
for x in range(len(uv)):
|
|
36
|
+
mapc2i[uv[x]] = x
|
|
37
|
+
print(f"Correspondance entre chaque catégorie unique et un entier : {mapc2i}")
|
|
38
|
+
y1ohe = y2c(mapc2i,y1)
|
|
39
|
+
y2ohe = y2c(mapc2i,y2)
|
|
40
|
+
print(f"Structure (shape) des tableaux renvoyés par categorize1C_2ohe. y1 : {y1ohe.shape}, y2 : {y2ohe.shape}")
|
|
41
|
+
del mapc2i, uv
|
|
42
|
+
return y1ohe, y2ohe
|
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
############################################################
|
|
2
|
+
# Periodic Table
|
|
3
|
+
############################################################
|
|
4
|
+
from .visualID_Eng import fg, bg, hl
|
|
5
|
+
from .core import centerTitle, centertxt
|
|
6
|
+
|
|
7
|
+
import mendeleev
|
|
8
|
+
|
|
9
|
+
class TableauPeriodique:
|
|
10
|
+
nomsFr=['Hydrogène','Hélium','Lithium','Béryllium','Bore','Carbone','Azote','Oxygène',
|
|
11
|
+
'Fluor','Néon','Sodium','Magnésium','Aluminium','Silicium','Phosphore','Soufre',
|
|
12
|
+
'Chlore','Argon','Potassium','Calcium','Scandium','Titane','Vanadium','Chrome',
|
|
13
|
+
'Manganèse','Fer','Cobalt','Nickel','Cuivre','Zinc','Gallium','Germanium',
|
|
14
|
+
'Arsenic','Sélénium','Brome','Krypton','Rubidium','Strontium','Yttrium',
|
|
15
|
+
'Zirconium','Niobium','Molybdène','Technétium','Ruthénium','Rhodium',
|
|
16
|
+
'Palladium','Argent','Cadmium','Indium',
|
|
17
|
+
'Étain','Antimoine','Tellure','Iode','Xénon','Césium','Baryum','Lanthane','Cérium',
|
|
18
|
+
'Praséodyme','Néodyme','Prométhium','Samarium','Europium','Gadolinium','Terbium',
|
|
19
|
+
'Dysprosium','Holmium','Erbium','Thulium','Ytterbium','Lutetium','Hafnium','Tantale',
|
|
20
|
+
'Tungstène','Rhénium','Osmium','Iridium','Platine','Or','Mercure','Thallium','Plomb',
|
|
21
|
+
'Bismuth','Polonium','Astate','Radon','Francium','Radium','Actinium','Thorium','Protactinium',
|
|
22
|
+
'Uranium','Neptunium','Plutonium','Americium','Curium','Berkelium','Californium','Einsteinium',
|
|
23
|
+
'Fermium','Mendelevium','Nobelium','Lawrencium','Rutherfordium','Dubnium','Seaborgium','Bohrium',
|
|
24
|
+
'Hassium','Meitnerium','Darmstadtium','Roentgenium','Copernicium','Nihonium','Flerovium',
|
|
25
|
+
'Moscovium','Livermorium','Tennesse','Oganesson',
|
|
26
|
+
]
|
|
27
|
+
trad = {'Nonmetals':'Non métal',
|
|
28
|
+
'Noble gases':'Gaz noble',
|
|
29
|
+
'Alkali metals':'Métal alcalin',
|
|
30
|
+
'Alkaline earth metals':'Métal alcalino-terreux',
|
|
31
|
+
'Metalloids':'Métalloïde',
|
|
32
|
+
'Halogens':'Halogène',
|
|
33
|
+
'Poor metals':'Métal pauvre',
|
|
34
|
+
'Transition metals':'Métal de transition',
|
|
35
|
+
'Lanthanides':'Lanthanide',
|
|
36
|
+
'Actinides':'Actinide',
|
|
37
|
+
'Metals':'Métal',
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
def __init__(self):
|
|
41
|
+
from mendeleev.vis import create_vis_dataframe
|
|
42
|
+
self.elements = create_vis_dataframe()
|
|
43
|
+
self.patch_elements()
|
|
44
|
+
|
|
45
|
+
def patch_elements(self):
|
|
46
|
+
'''
|
|
47
|
+
Ce patch, appliqué à self.elements, créé par l'appel à create_vis_dataframe(), va servir à :
|
|
48
|
+
- ajouter des informations en français : les noms des éléments et des séries (familles) auxquelles ils appartiennent
|
|
49
|
+
- retirer les éléments du groupe 12 de la famille des métaux de transition, qui est le choix CONTESTABLE par défaut de la bibliothèque mendeleev
|
|
50
|
+
input : elements est un dataframe pandas préalablement créé par la fonction create_vis_dataframe() de mendeleev.vis
|
|
51
|
+
output : elements avec deux nouvelles colonnes name_seriesFr et nom, qui contient dorénavant les noms des éléments en français
|
|
52
|
+
+ correction des données name_series et series_id pour les éléments Zn, Cd, Hg, Cn
|
|
53
|
+
+ de nouvelles colonnes qui contiennent l'énergie de première ionisation et les isotopes naturels
|
|
54
|
+
'''
|
|
55
|
+
def series_eng2fr(s):
|
|
56
|
+
'''Correspondance entre nom des séries (familles) en anglais et en français'''
|
|
57
|
+
s = TableauPeriodique.trad[s]
|
|
58
|
+
return s
|
|
59
|
+
|
|
60
|
+
def name_eng2fr():
|
|
61
|
+
self.elements["nom"] = TableauPeriodique.nomsFr
|
|
62
|
+
return
|
|
63
|
+
|
|
64
|
+
def ajouter_donnees():
|
|
65
|
+
import numpy as np
|
|
66
|
+
from mendeleev.fetch import fetch_table, fetch_ionization_energies
|
|
67
|
+
import pandas as pd
|
|
68
|
+
# dfElts = fetch_table("elements")
|
|
69
|
+
# display(dfElts)
|
|
70
|
+
dfEi1 = fetch_ionization_energies(degree = 1)
|
|
71
|
+
# display(dfEi1)
|
|
72
|
+
b = pd.DataFrame({'atomic_number':[x for x in range(1, 119)]})
|
|
73
|
+
dfEi1tot = pd.merge(left=dfEi1, right=b, on='atomic_number', how='outer').sort_values(by='atomic_number')
|
|
74
|
+
self.elements["Ei1"] = dfEi1tot["IE1"]
|
|
75
|
+
|
|
76
|
+
# les éléments du groupe 12 ne sont pas des métaux de transition
|
|
77
|
+
self.elements.loc[29,"name_series"] = 'Metals'
|
|
78
|
+
self.elements.loc[47,"name_series"] = 'Metals'
|
|
79
|
+
self.elements.loc[79,"name_series"] = 'Metals'
|
|
80
|
+
self.elements.loc[111,"name_series"] = 'Metals'
|
|
81
|
+
self.elements.loc[29,"series_id"] = 11
|
|
82
|
+
self.elements.loc[47,"series_id"] = 11
|
|
83
|
+
self.elements.loc[79,"series_id"] = 11
|
|
84
|
+
self.elements.loc[111,"series_id"] = 11
|
|
85
|
+
self.elements.loc[29,"color"] = "#bbd3a5"
|
|
86
|
+
self.elements.loc[47,"color"] = "#bbd3a5"
|
|
87
|
+
self.elements.loc[79,"color"] = "#bbd3a5"
|
|
88
|
+
self.elements.loc[111,"color"] = "#bbd3a5"
|
|
89
|
+
# english > français. Ajout d'une nouvelle colonne
|
|
90
|
+
self.elements["name_seriesFr"] = self.elements["name_series"].apply(series_eng2fr)
|
|
91
|
+
# english > français. Noms des éléments en français changés dans la colonne name
|
|
92
|
+
name_eng2fr()
|
|
93
|
+
ajouter_donnees()
|
|
94
|
+
return
|
|
95
|
+
|
|
96
|
+
def prop(self,elt_id):
|
|
97
|
+
from mendeleev import element
|
|
98
|
+
|
|
99
|
+
elt = element(elt_id)
|
|
100
|
+
print(f"Nom de l'élement = {TableauPeriodique.nomsFr[elt.atomic_number-1]} ({elt.symbol}, Z = {elt.atomic_number})")
|
|
101
|
+
print(f"Nom en anglais = {elt.name}")
|
|
102
|
+
print(f"Origine du nom = {elt.name_origin}")
|
|
103
|
+
print()
|
|
104
|
+
print(f"CEF = {elt.ec} = {elt.econf}")
|
|
105
|
+
print(f"Nombre d'électrons célibataires = {elt.ec.unpaired_electrons()}")
|
|
106
|
+
print(f"Groupe {elt.group_id}, Période {elt.period}, bloc {elt.block}")
|
|
107
|
+
print(f"Famille = {self.elements.loc[elt.atomic_number-1,'name_seriesFr']}")
|
|
108
|
+
print()
|
|
109
|
+
print(f"Masse molaire = {elt.atomic_weight} g/mol")
|
|
110
|
+
isotopes = ""
|
|
111
|
+
X = elt.symbol
|
|
112
|
+
for i in elt.isotopes:
|
|
113
|
+
if i.abundance is not None:
|
|
114
|
+
isotopes = isotopes + str(i.mass_number)+ "^" + X + f"({i.abundance}%) / "
|
|
115
|
+
print("Isotopes naturels = ",isotopes[:-2])
|
|
116
|
+
print()
|
|
117
|
+
if elt.electronegativity(scale='pauling') is None:
|
|
118
|
+
print(f"Électronégativité de Pauling = Non définie")
|
|
119
|
+
else:
|
|
120
|
+
print(f"Électronégativité de Pauling = {elt.electronegativity(scale='pauling')}")
|
|
121
|
+
print(f"Énergie de 1ère ionisation = {elt.ionenergies[1]:.2f} eV")
|
|
122
|
+
if elt.electron_affinity is None:
|
|
123
|
+
print(f"Affinité électronique = Non définie")
|
|
124
|
+
else:
|
|
125
|
+
print(f"Afinité électronique = {elt.electron_affinity:.2f} eV")
|
|
126
|
+
print(f"Rayon atomique = {elt.atomic_radius:.1f} pm")
|
|
127
|
+
print()
|
|
128
|
+
print("▶ Description : ",elt.description)
|
|
129
|
+
print("▶ Sources : ",elt.sources)
|
|
130
|
+
print("▶ Utilisation : ",elt.uses)
|
|
131
|
+
print("---------------------------------------------------------------------------------------")
|
|
132
|
+
print()
|
|
133
|
+
|
|
134
|
+
def afficher(self):
|
|
135
|
+
from bokeh.plotting import show, output_notebook
|
|
136
|
+
from mendeleev.vis import periodic_table_bokeh
|
|
137
|
+
|
|
138
|
+
# Toute cette partie du code est une copie du module bokeh de mendeleev.vis
|
|
139
|
+
# La fonction periodic_table_bokeh étant faiblement configurable avec des args/kwargs,
|
|
140
|
+
# elle est adaptée ici pour un affichage personnalisé
|
|
141
|
+
|
|
142
|
+
from collections import OrderedDict
|
|
143
|
+
|
|
144
|
+
import pandas as pd
|
|
145
|
+
from pandas.api.types import is_float_dtype
|
|
146
|
+
|
|
147
|
+
from bokeh.plotting import figure
|
|
148
|
+
from bokeh.models import HoverTool, ColumnDataSource, FixedTicker
|
|
149
|
+
|
|
150
|
+
from mendeleev.vis.utils import colormap_column
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
def periodic_table_bokeh(
|
|
154
|
+
elements: pd.DataFrame,
|
|
155
|
+
attribute: str = "atomic_weight",
|
|
156
|
+
cmap: str = "RdBu_r",
|
|
157
|
+
colorby: str = "color",
|
|
158
|
+
decimals: int = 3,
|
|
159
|
+
height: int = 800,
|
|
160
|
+
missing: str = "#ffffff",
|
|
161
|
+
title: str = "Periodic Table",
|
|
162
|
+
wide_layout: bool = False,
|
|
163
|
+
width: int = 1200,
|
|
164
|
+
):
|
|
165
|
+
"""
|
|
166
|
+
Use Bokeh backend to plot the periodic table. Adaptation by Romuald Poteau (romuald.poteau@univ-tlse3.fr) of the orignal periodic_table_bokeh() function of the mendeleev library
|
|
167
|
+
|
|
168
|
+
Args:
|
|
169
|
+
elements : Pandas DataFrame with the elements data. Needs to have `x` and `y`
|
|
170
|
+
columns with coordianates for each tile.
|
|
171
|
+
attribute : Name of the attribute to be displayed
|
|
172
|
+
cmap : Colormap to use, see matplotlib colormaps
|
|
173
|
+
colorby : Name of the column containig the colors
|
|
174
|
+
decimals : Number of decimals to be displayed in the bottom row of each cell
|
|
175
|
+
height : Height of the figure in pixels
|
|
176
|
+
missing : Hex code of the color to be used for the missing values
|
|
177
|
+
title : Title to appear above the periodic table
|
|
178
|
+
wide_layout: wide layout variant of the periodic table
|
|
179
|
+
width : Width of the figure in pixels
|
|
180
|
+
"""
|
|
181
|
+
|
|
182
|
+
if any(col not in elements.columns for col in ["x", "y"]):
|
|
183
|
+
raise ValueError(
|
|
184
|
+
"Coordinate columns named 'x' and 'y' are required "
|
|
185
|
+
"in 'elements' DataFrame. Consider using "
|
|
186
|
+
"'mendeleev.vis.utils.create_vis_dataframe' and try again."
|
|
187
|
+
)
|
|
188
|
+
|
|
189
|
+
# additional columns for positioning of the text
|
|
190
|
+
|
|
191
|
+
elements.loc[:, "y_anumber"] = elements["y"] - 0.3
|
|
192
|
+
elements.loc[:, "y_name"] = elements["y"] + 0.2
|
|
193
|
+
|
|
194
|
+
if attribute:
|
|
195
|
+
elements.loc[elements[attribute].notnull(), "y_prop"] = (
|
|
196
|
+
elements.loc[elements[attribute].notnull(), "y"] + 0.35
|
|
197
|
+
)
|
|
198
|
+
else:
|
|
199
|
+
elements.loc[:, "y_prop"] = elements["y"] + 0.35
|
|
200
|
+
|
|
201
|
+
ac = "display_attribute"
|
|
202
|
+
if is_float_dtype(elements[attribute]):
|
|
203
|
+
elements[ac] = elements[attribute].round(decimals=decimals)
|
|
204
|
+
else:
|
|
205
|
+
elements[ac] = elements[attribute]
|
|
206
|
+
|
|
207
|
+
if colorby == "attribute":
|
|
208
|
+
colored = colormap_column(elements, attribute, cmap=cmap, missing=missing)
|
|
209
|
+
elements.loc[:, "attribute_color"] = colored
|
|
210
|
+
colorby = "attribute_color"
|
|
211
|
+
|
|
212
|
+
# bokeh configuration
|
|
213
|
+
|
|
214
|
+
source = ColumnDataSource(data=elements)
|
|
215
|
+
|
|
216
|
+
TOOLS = "hover,save,reset"
|
|
217
|
+
|
|
218
|
+
fig = figure(
|
|
219
|
+
title=title,
|
|
220
|
+
tools=TOOLS,
|
|
221
|
+
x_axis_location="above",
|
|
222
|
+
x_range=(elements.x.min() - 0.5, elements.x.max() + 0.5),
|
|
223
|
+
y_range=(elements.y.max() + 0.5, elements.y.min() - 0.5),
|
|
224
|
+
width=width,
|
|
225
|
+
height=height,
|
|
226
|
+
toolbar_location="above",
|
|
227
|
+
toolbar_sticky=False,
|
|
228
|
+
)
|
|
229
|
+
|
|
230
|
+
fig.rect("x", "y", 0.9, 0.9, source=source, color=colorby, fill_alpha=0.6)
|
|
231
|
+
|
|
232
|
+
# adjust the ticks and axis bounds
|
|
233
|
+
fig.yaxis.bounds = (1, 7)
|
|
234
|
+
fig.axis[1].ticker.num_minor_ticks = 0
|
|
235
|
+
if wide_layout:
|
|
236
|
+
# Turn off tick labels
|
|
237
|
+
fig.axis[0].major_label_text_font_size = "0pt"
|
|
238
|
+
# Turn off tick marks
|
|
239
|
+
fig.axis[0].major_tick_line_color = None # turn off major ticks
|
|
240
|
+
fig.axis[0].ticker.num_minor_ticks = 0 # turn off minor ticks
|
|
241
|
+
else:
|
|
242
|
+
fig.axis[0].ticker = FixedTicker(ticks=list(range(1, 19)))
|
|
243
|
+
|
|
244
|
+
text_props = {
|
|
245
|
+
"source": source,
|
|
246
|
+
"angle": 0,
|
|
247
|
+
"color": "black",
|
|
248
|
+
"text_align": "center",
|
|
249
|
+
"text_baseline": "middle",
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
fig.text(
|
|
253
|
+
x="x",
|
|
254
|
+
y="y",
|
|
255
|
+
text="symbol",
|
|
256
|
+
text_font_style="bold",
|
|
257
|
+
text_font_size="15pt",
|
|
258
|
+
**text_props,
|
|
259
|
+
)
|
|
260
|
+
fig.text(
|
|
261
|
+
x="x", y="y_anumber", text="atomic_number", text_font_size="9pt", **text_props
|
|
262
|
+
)
|
|
263
|
+
fig.text(x="x", y="y_name", text="name", text_font_size="6pt", **text_props)
|
|
264
|
+
fig.text(x="x", y="y_prop", text=ac, text_font_size="7pt", **text_props)
|
|
265
|
+
|
|
266
|
+
fig.grid.grid_line_color = None
|
|
267
|
+
|
|
268
|
+
hover = fig.select(dict(type=HoverTool))
|
|
269
|
+
hover.tooltips = OrderedDict(
|
|
270
|
+
[
|
|
271
|
+
("nom", "@nom"),
|
|
272
|
+
("name", "@name"),
|
|
273
|
+
("famille", "@name_seriesFr"),
|
|
274
|
+
("numéro atomique", "@atomic_number"),
|
|
275
|
+
("masse molaire", "@atomic_weight"),
|
|
276
|
+
("rayon atomique", "@atomic_radius"),
|
|
277
|
+
("énergie de première ionisation", "@Ei1"),
|
|
278
|
+
("affinité électronique", "@electron_affinity"),
|
|
279
|
+
("EN Pauling", "@en_pauling"),
|
|
280
|
+
("CEF", "@electronic_configuration"),
|
|
281
|
+
]
|
|
282
|
+
)
|
|
283
|
+
|
|
284
|
+
return fig
|
|
285
|
+
|
|
286
|
+
output_notebook()
|
|
287
|
+
|
|
288
|
+
fig = periodic_table_bokeh(self.elements, colorby="color")
|
|
289
|
+
show(fig)
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# tools4pyPhysChem/__init__.py
|
|
2
|
+
__version__ = "0.1.0"
|
|
3
|
+
__last_update__ = "2026-02-01"
|
|
4
|
+
|
|
5
|
+
import importlib
|
|
6
|
+
import importlib.util
|
|
7
|
+
|
|
8
|
+
# 1. FAST IMPORTS
|
|
9
|
+
from .visualID_Eng import fg, hl, bg, color, init, apply_css_style, chrono_start, chrono_stop, end
|
|
10
|
+
from .core import centerTitle, centertxt, crop_images
|
|
11
|
+
|
|
12
|
+
# On définit explicitement ce qui est déjà importé pour que __getattr__ ne s'en mêle pas
|
|
13
|
+
_EXPLICIT_EXPORTS = {
|
|
14
|
+
"fg", "hl", "bg", "color", "init", "apply_css_style",
|
|
15
|
+
"chrono_start", "chrono_stop", "end", "centerTitle",
|
|
16
|
+
"centertxt", "crop_images"
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
# 2. AUTOMATIC LAZY LOADING
|
|
20
|
+
def __getattr__(name):
|
|
21
|
+
# Si l'attribut est dans les imports explicites, on ne devrait pas être ici,
|
|
22
|
+
# mais au cas où, on le gère.
|
|
23
|
+
if name in _EXPLICIT_EXPORTS:
|
|
24
|
+
# On le récupère dans le namespace local
|
|
25
|
+
return globals()[name]
|
|
26
|
+
|
|
27
|
+
modules_to_search = [
|
|
28
|
+
".ML", ".PeriodicTable", ".Chem3D",
|
|
29
|
+
".aithermo", ".cheminformatics", ".kinetics", # Virgule corrigée ici
|
|
30
|
+
".spectra", ".survey",
|
|
31
|
+
".sympyUtilities", ".tools4AS"
|
|
32
|
+
]
|
|
33
|
+
|
|
34
|
+
for mod_name in modules_to_search:
|
|
35
|
+
try:
|
|
36
|
+
# On tente l'import relatif
|
|
37
|
+
module = importlib.import_module(mod_name, __package__)
|
|
38
|
+
if hasattr(module, name):
|
|
39
|
+
return getattr(module, name)
|
|
40
|
+
except (ImportError, AttributeError):
|
|
41
|
+
continue
|
|
42
|
+
|
|
43
|
+
raise AttributeError(f"module {__name__} has no attribute {name}")
|