pyphyschemtools package

The pyphyschemtools library provides a comprehensive suite of utilities for Physical Chemistry, ranging from spectroscopic unit management to kinetic modeling and cheminformatics.

pyphyschemtools.save_data(df, path_with_name: str, **kwargs)[source]

Saves a Pandas DataFrame to CSV or Excel, automatically creating missing directories.

Parameters:
  • df (pd.DataFrame) – The DataFrame to save.

  • path_with_name (str) – The path and filename (e.g., “data/results.csv”).

  • **kwargs – Additional arguments passed to to_csv or to_excel (e.g., index=True).

pyphyschemtools.save_fig(path_with_name: str, fig=None, dpi: int = 300, **kwargs)[source]

Saves a figure to a path, automatically creating missing directories. Works with the current plt or a specific figure object.

Parameters:
  • path_with_name (str) – The path and filename (e.g., “results/plots/energy.svg”).

  • fig (matplotlib.figure.Figure, optional) – A specific figure object. If None, uses plt.gcf().

  • dpi (int) – Resolution for raster formats. Defaults to 300.

  • **kwargs – Additional arguments passed to savefig (e.g., transparent=True).

Subpackages

Submodules

pyphyschemtools.AO module

Atomic orbitals of the hydrogen atom and hydrogenic ions: radial parts, real spherical harmonics, and their visualization (radial plots, 2D polar cross-sections, electron cloud projections, and interactive 3D nodal surfaces).

Public functions: - plot_radial : radial part R_nl(r) or radial probability density - plot_polar : 2D polar diagram of the angular part, in a chosen plane - plot_electron_cloud : electron cloud of an orbital (density-weighted point sampling), projected onto a chosen plane - plot_orbital_3D : interactive 3D nodal surfaces of an orbital (radial nodes as spheres, angular nodes as cones and planes), with the electron cloud as an optional overlay

pyphyschemtools.AO.plot_electron_cloud(n, l, m, plane='xz', Z=1, n_points=20000, point_size=3, alpha=0.25, color_pos='tab:blue', color_neg='tab:red', size=(6, 6), show_formula=False, save_as=None)[source]

Draw the electron cloud of a hydrogenic orbital psi_nlm, projected onto a plane, as a density-weighted point cloud: points are sampled with probability proportional to |psi_nlm|^2 (rejection sampling in 3D, see _sample_orbital_cloud), then projected onto the chosen plane. Both radial nodes (R_nl(r) = 0) and angular nodes (Z_l^m = 0) appear as empty regions, since no points are sampled there – no separate geometric reconstruction is needed.

input:

  • n, l, m = quantum numbers of the orbital (0 <= l <= n-1, -l <= m <= l)

  • plane = projection plane: “xy”, “xz” or “yz” (default: “xz”)

  • Z = nuclear charge (default: 1 for hydrogen)

  • n_points = number of sampled points

  • point_size, alpha = marker size and transparency of each point

  • color_pos, color_neg = colors for points where psi_nlm is positive / negative

  • size = (width, height) in inches for the figure

  • show_formula = if True, display (via IPython) the symbolic expressions of R_nl(r) and Z_l^m(theta, phi)

  • save_as = file path to save the figure to (passed to pyphyschemtools.core’s save_fig); not saved if None (default)

output: None (the figure is drawn and shown, and saved if save_as is given)

pyphyschemtools.AO.plot_orbital_3D(n, l, m, Z=1, prob_fraction=0.7, show_nodes=True, show_cloud=False, n_points=20000, point_size=2, color_pos='blue', color_neg='red', grid_points=60, width=900, height=900, show_formula=False, save_as=None)[source]

Draw the 3D shape of a hydrogenic orbital psi_nlm as isosurfaces: the surface(s) where |psi_nlm| = iso_fraction * max(|psi_nlm|), colored by the sign of psi_nlm. For orbitals with radial nodes (n-l-1 > 0), this naturally shows nested lobes – a smaller inner surface inside a larger outer one (e.g. 2s, 3p, 4d, 
), with no extra work needed: the isosurface algorithm finds every disconnected region on its own.

Optionally, the exact nodal surfaces (show_nodes=True) and/or the density-weighted electron cloud (show_cloud=True) can be overlaid.

input:

  • n, l, m = quantum numbers of the orbital (0 <= l <= n-1, -l <= m <= l)

  • Z = nuclear charge (default: 1 for hydrogen)

  • prob_fraction = fraction of the total electron probability enclosed by the lobe surfaces (default: 0.7 – higher shows fatter lobes)

  • show_nodes = if True, also draw the exact nodal surfaces (radial spheres, angular cones/planes); default: True

  • show_cloud = if True, also draw the sampled electron cloud; default: False

  • n_points = number of sampled points for the cloud (only used if show_cloud=True)

  • point_size = marker size for the cloud points

  • color_pos, color_neg = colors for the lobes/cloud points where psi_nlm is positive / negative

  • grid_points = resolution (per axis) of the 3D grid used for the lobe isosurfaces

  • width, height = size of the figure, in pixels

  • show_formula = if True, display (via IPython) the symbolic expressions of R_nl(r) and Z_l^m(theta, phi)

  • save_as = file path to save the figure to, as a static image (requires kaleido) or an interactive .html; format taken from the extension. Not saved if None (default)

output: None (the figure is shown interactively, and saved if save_as is given)

pyphyschemtools.AO.plot_polar(l, m, plane='xy', density=False, show_formula=False, n_points=400, size=(6, 6), save_as=None)[source]

Draw the 2D polar diagram of the angular part of an atomic orbital (the real spherical harmonic Z_lm, independent of n) in a plane containing the origin.

A sweep angle gamma (0 to 2*pi) runs once around the chosen plane; at each gamma the corresponding direction (theta, phi) is computed, and the radius plotted is |Z_lm(theta, phi)| (or its square if density=True). The two signs of Z_lm are filled in different colors, so the lobes of p, d, 
 orbitals and their phase change are visible; the radius goes to zero at a node (sign change).

input:

  • l = orbital angular momentum quantum number (l >= 0)

  • m = magnetic quantum number (-l <= m <= l)

  • plane = projection plane: “xy”, “xz” or “yz” (default: “xy”)

  • density = if False (default), plot |Z_lm|; if True, plot the angular probability density Z_lm^2

  • show_formula = if True, display (via IPython) the symbolic expression of the quantity plotted (and its squared/density form if density=True); default: False

  • n_points = number of points used to sample the sweep angle

  • size = (width, height) in inches for the figure

  • save_as = file path to save the figure to (passed to pyphyschemtools.core’s save_fig); not saved if None (default)

output: None (the figure is drawn and shown, and saved if save_as is given)

pyphyschemtools.AO.plot_radial(orbitals, Z=1, density=False, show_formula=False, r_max=None, n_points=500, size=(9, 5), save_as=None)[source]

Plot the radial part R_nl(r) (default) or the radial probability density r^2 R_nl(r)^2 of one or several hydrogenic atomic orbitals, as a function of r (in units of the Bohr radius a0, scaled by 1/Z).

input:

  • orbitals = list of (n, l) tuples, one curve per orbital, e.g. [(1, 0), (2, 0), (2, 1)] for 1s, 2s, 2p

  • Z = nuclear charge (default: 1 for hydrogen)

  • density = if False (default), plot R_nl(r); if True, plot the radial probability density r^2 R_nl(r)^2 (probability of finding the electron in a thin spherical shell at r)

  • show_formula = if True, display (via IPython) the symbolic expression of the quantity plotted (and its squared/density form if density=True); default: False

  • r_max = largest r shown, in units of a0/Z; if None (default), set automatically from the largest n among orbitals

  • n_points = number of points used to sample r

  • size = (width, height) in inches for the figure

  • save_as = file path to save the figure to (passed to pyphyschemtools.core’s save_fig); not saved if None (default)

output: None (the figure is drawn and shown, and saved if save_as is given)

pyphyschemtools.Chem3D module

class pyphyschemtools.Chem3D.XYZData(symbols, positions)[source]

Bases: object

Object containing molecular coordinates and symbols extracted by molView. Allows for geometric calculations without reloading data.

get_bounding_sphere(include_vdw=True, scale=1.0)[source]

Calculates the center and radius of the bounding sphere using ASE. scale: multiplication factor (e.g., 0.6 to match a reduced CPK style).

get_cage_volume(grid_spacing=0.5, return_spheres=False)[source]

Calculates the internal cavity volume of a molecular cage using CageCavityCalc.

This method interfaces with the CageCavityCalc library by generating a temporary PDB file of the current structure. It can also retrieve the coordinates of the ‘dummy atoms’ (points) that fill the detected void.

Parameters:
  • grid_spacing (float, optional) – The resolution of the grid used for volume integration in Å. Smaller values provide higher precision (default: 0.5).

  • return_spheres (bool, optional) – If True, returns both the volume and an ase.Atoms object containing the dummy atoms representing the cavity (default: False).

Returns:

  • volume (float or None) – The calculated cavity volume in ų. Returns None if the calculation fails.

  • cavity_atoms (ase.Atoms, optional) – Returned only if return_spheres is True. An ASE Atoms object representing the internal void space.

get_cavity_dimensions(cavity_atoms)[source]

Calculates the principal dimensions (Length, Width, Height) of the cavity points.

This method uses Principal Component Analysis (PCA) to find the natural axes of the cavity, making it independent of the molecule’s orientation. Percentiles are used instead of absolute Max-Min to filter out potential outliers or ‘leaking’ points at the openings.

Parameters:

cavity_atoms (ase.Atoms) – The Atoms object containing the ‘dummy atoms’ generated by the cavity calculation.

Returns:

The dimensions (L, W, H) sorted from largest to smallest.

Return type:

tuple (float, float, float)

get_center_of_geometry()[source]

Calculates the arithmetic mean of the atomic positions (Centroid).

get_center_of_mass()[source]
class pyphyschemtools.Chem3D.molView(mol, source=None, style='bs', displayHbonds=True, cpk_scale=0.6, w=600, h=400, supercell=(1, 1, 1), display_now=True, detect_BondOrders=True, viewer=True, zoom=None, show_n=False, highlight_atoms=None, highlight_color='yellow', highlight_scale=1.3, prefer_local_3d=False)[source]

Bases: object

Initializes a molecular/crystal viewer and coordinate extractor.

This class acts as a bridge between various molecular data sources and the py3Dmol interactive viewer. It can operate in ‘Full’ mode (display + analysis) or ‘Headless’ mode (analysis only) by toggling the viewer parameter.

The class automatically extracts geometric data into the self.data attribute (an XYZData object), allowing for volume, dimension, and cavity calculations.

Display molecular and crystal structures in py3Dmol from various sources:

  • XYZ/PDB/CIF local files

  • XYZ-format string

  • PubChem CID

  • ASE Atoms object

  • COD ID

  • RCSB PDB ID

  • SMILES string (PubChem lookup by default, optional local RDKit 3D generation)

Three visualization styles are available:

  • ‘bs’ : ball-and-stick (default)

  • ‘cpk’ : CPK space-filling spheres (with adjustable size)

  • ‘cartoon’: protein backbone representation

Upon creation, an interactive 3D viewer is shown directly in a Jupyter notebook cell, unless the headless viewer parameter is set to False.

Parameters:
  • mol (str or ase.Atoms) –

    The molecular structure to visualize.

    • If source=’file’, this should be a path to a structure file (XYZ, PDB, etc.)

    • If source=’mol’, this should be a string containing the structure (XYZ, PDB, MDL mol/SDF
)

    • If source=’cif’, this should be a cif file (string)

    • If source=’cid’, this should be a PubChem CID (string or int)

    • If source=’rcsb’, this should be a RCSB PDB ID (string)

    • If source=’cod’, this should be a COD ID (string)

    • If source=’ase’, this should be an ase.Atoms object

    • If source=’smiles’, this should be a SMILES string

  • source ({'file', 'mol', 'cif', 'cid', 'rcsb', 'ase', 'smiles'}, optional) – The type of the input mol (default: ‘file’).

  • style ({'bs', 'cpk', 'cartoon'}, optional) –

    Visualization style (default: ‘bs’).

    • ’bs’ → ball-and-stick

    • ’cpk’ → CPK space-filling spheres

    • ’cartoon’ → draws a smooth tube or ribbon through the protein backbone

      (default for pdb structures)

  • displayHbonds (plots hydrogen bonds (default: True))

  • cpk_scale (float, optional) – Overall scaling factor for sphere size in CPK style (default: 0.5). Ignored when style=’bs’.

  • supercell (tuple of int) – Repetition of the unit cell (na, nb, nc). Default is (1, 1, 1).

  • w (int, optional) – Width of the viewer in pixels (default: 600).

  • h (int, optional) – Height of the viewer in pixels (default: 400).

  • detect_BondOrders (bool, optional) – If True (default) and input is XYZ, uses RDKit to perceive connectivity and bond orders (detects double/triple bonds). Requires the rdkit library. If False, fallback to standard 3Dmol distance-based single bonds.

  • display_now (bool, optional) – If True (default), renders the molecule immediately. Set to False to prevent immediate display when you plan to call further visualization methods provided by the molView class

  • viewer (bool, optional) – If True (default), initializes the py3Dmol engine and prepares the 3D model. If False, operates in ‘headless’ mode: only geometric data is processed for analysis (volume, CM, etc.), saving significant memory for high-throughput processing.

  • zoom (None, optional) – scaling factor

  • show_n (bool, optional) – If True, permanently displays each atom’s element symbol and index directly on the figure (as opposed to on-hover labels). Default: False.

  • highlight_atoms (list of int, optional) – Indices of atoms to highlight with an overlaid translucent sphere, without altering the base style (bs/cpk/cartoon). Default: None.

  • highlight_color (str, optional) – Color of the highlight overlay (default: ‘yellow’). Ignored if highlight_atoms is None.

  • highlight_scale (float, optional) – Scale factor of the highlight sphere relative to the atom’s own sphere (default: 1.3). Ignored if highlight_atoms is None.

  • prefer_local_3d (bool, optional) – Only used when source=’smiles’. If True, generates the 3D structure locally with RDKit instead of querying PubChem (default: False).

data

Container for atomic symbols and positions, used for geometric analysis.

Type:

XYZData or None

v

The 3Dmol.js viewer instance (None if viewer=False).

Type:

py3Dmol.view or None

Examples

>>> molView("molecule.xyz", source="file")
>>> molView(xyz_string, source="mol")
>>> molView(2244, source="cid")   # PubChem aspirin
>>> from ase.build import molecule
>>> molView(molecule("H2O"), source="ase")
>>> molView.view_grid([2244, 2519, 702], n_cols=3, source='cid', style='bs')
>>> molView.view_grid(xyzFiles, n_cols=3, source='file', style='bs', titles=titles, w=500, sync=True)
>>> # Headless mode for high-throughput volume calculations
>>> mv = molView("cage.xyz", viewer=False)
>>> vol = mv.data.get_cage_volume()
>>> # Permanent atom numbering on the figure
>>> molView("molecule.xyz", source="file", show_n=True)
>>> # Highlight a reactive center (e.g. atoms 0 and 5) without changing the style
>>> molView("molecule.xyz", source="file", highlight_atoms=[0, 5], highlight_color="magenta")
analyze_symmetry(tolerance=0.3, angle_tolerance=5.0, eigen_tolerance=0.01, matrix_tolerance=0.1)[source]

Comprehensive symmetry analysis using Pymatgen.

Parameters:
  • tolerance (float) – Distance tolerance in Å (symprec for crystals). Default 0.3.

  • angle_tolerance (float) – Angular tolerance in degrees (Crystals only). Default 5.0.

  • eigen_tolerance (float) – Inertia tensor eigenvalue tolerance (Molecules only). Default 0.01.

  • matrix_tolerance (float) – Symmetry operation matrix tolerance (Molecules only). Default 0.1.

show_bounding_sphere(color='gray', opacity=0.2, scale=1.0)[source]

Calculates and displays the VdW bounding sphere in one go.

show_cage_cavity(grid_spacing=0.5, color='cyan', opacity=0.5)[source]

Calculates cavity with CageCavityCalc and displays it as a single model.

classmethod view_grid(mol_list, n_cols=3, titles=None, **kwargs)[source]

Displays a list of molecular structures in an interactive n_rows x n_cols grid.

This method uses ipywidgets.GridspecLayout to organize multiple 3D viewers into a clean matrix. It automatically calculates the required number of rows based on the length of the input list.

Parameters:
  • mol_list (list) – A list containing the molecular data to visualize. Elements should match the expected ‘mol’ input for the class (paths, CIDs, strings, etc.).

  • n_cols (int, optional) – Number of columns in the grid (default: 3).

  • titles (list of str, optional) – Custom labels for each cell. If None, the string representation of the ‘mol’ input is used as the title.

  • **kwargs (dict) – Additional arguments passed to the molView constructor: - source : {‘file’, ‘mol’, ‘cif’, ‘cid’, ‘rcsb’, ‘ase’} - style : {‘bs’, ‘cpk’, ‘cartoon’} - displayHbonds : plots hydrogen bonds (default: True) - w : width of each individual viewer in pixels (default: 300) - h : height of each individual viewer in pixels (default: 300) - supercell : tuple (na, nb, nc) for crystal structures - cpk_scale : scaling factor for space-filling spheres

Returns:

A widget object containing the grid of molecular viewers.

Return type:

ipywidgets.GridspecLayout

Examples

>>> files = ["mol1.xyz", "mol2.xyz", "mol3.xyz", "mol4.xyz"]
>>> labels = ["Reactant", "TS", "Intermediate", "Product"]
>>> molView.view_grid(files, n_cols=2, titles=labels, source='file', w=400)

pyphyschemtools.ML module

pyphyschemtools.ML.categorizeY_2ohe(Ctot, y1, y2)[source]

one-hot-encodes a pandas column of categorical data

input:

  • Ctot is the reference pandas column, necessary to find all unique categories in this column

  • 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

output:

  • y1ohe and y2ohe are the numpy arrays returned by this routine

pyphyschemtools.ML.y2c(mc2i, y)[source]

pyphyschemtools.PeriodicTable module

class pyphyschemtools.PeriodicTable.PeriodicTable[source]

Bases: TableauPeriodique

English-language counterpart of TableauPeriodique.

Same underlying data (fetched through the ‘mendeleev’ library) and the same set of methods, but without the French localization patch: element and family/series names are left as mendeleev provides them (English), and all printed output (prop, isotopes, mononucleides) is in English.

Everything else — the group-12-is-not-a-transition-metal correction, the extra data merged in (first ionization energy), the radiogenic-isotope and CIAAW-interval warnings — is shared with TableauPeriodique via inheritance.

afficher()[source]

Generates and displays the interactive periodic table in a Jupyter notebook.

Hover over a tile to see the element’s properties.

isotopes(elt_id)[source]

Prints an element’s isotope table (mass number, natural abundance, half-life), sorted by increasing mass number.

Generalizes the thorium example: for a radioelement, the absence of an abundance value simply means that no isotope is stable/natural in mendeleev’s sense.

Parameters:

elt_id (str or int) – Element symbol (e.g. ‘Th’) or atomic number (e.g. 90).

mononucleides(exclude_radiogenic=True)[source]

Prints the mononuclidic elements, i.e. elements with a single isotope of measurable natural abundance (in mendeleev’s sense: abundance is not None).

Parameters:

exclude_radiogenic (bool) – if True (default), excludes elements such as thorium, reclassified as binuclidic (or more) by the IUPAC in 2013 because of a trace radiogenic isotope (see TableauPeriodique.exceptionsRadiogeniques).

prop(elt_id)[source]

Prints detailed properties of a chemical element.

Parameters:

elt_id (str or int) – Element symbol (e.g. ‘O’) or atomic number (e.g. 8).

class pyphyschemtools.PeriodicTable.TableauPeriodique[source]

Bases: object

Classe permettant de manipuler et d’afficher les donnĂ©es du tableau pĂ©riodique.

Cette classe utilise la bibliothĂšque ‘mendeleev’ pour rĂ©cupĂ©rer les donnĂ©es chimiques et ‘bokeh’ pour la visualisation interactive. Elle francise les noms et corrige certaines classifications de familles chimiques.

Initialise l’objet TableauPeriodique en chargeant les donnĂ©es de la bibliothĂšque mendeleev.

Note

See also PeriodicTable, the English-language counterpart of this class (same data and methods, but without the French localization patch).

afficher()[source]

GénÚre et affiche le tableau périodique interactif dans un notebook Jupyter.

Le tableau permet de visualiser les propriétés au survol de la souris.

exceptionsRadiogenic = {90: '230-Th, a decay product of 238U (IUPAC/CIAAW, 2013)'}
exceptionsRadiogeniques = {90: "230-Th, issu de la désintégration de l'238U (IUPAC/CIAAW, 2013)"}
intervallesCIAAW = {1: (1.00784, 1.00811), 3: (6.938, 6.997), 5: (10.806, 10.821), 6: (12.0096, 12.0116), 7: (14.00643, 14.00728), 8: (15.99903, 15.99977), 12: (24.304, 24.307), 14: (28.084, 28.086), 16: (32.059, 32.076), 17: (35.446, 35.457), 35: (79.901, 79.907), 81: (204.382, 204.385)}
isotopes(elt_id)[source]

Affiche la table des isotopes d’un Ă©lĂ©ment (numĂ©ro de masse, abondance naturelle, demi-vie), triĂ©e par numĂ©ro de masse croissant.

GĂ©nĂ©ralise l’exemple du thorium : pour un radioĂ©lĂ©ment, l’absence d’abondance signifie simplement qu’aucun isotope n’est stable/naturel au sens de mendeleev.

Parameters:

elt_id (str ou int) – Symbole de l’élĂ©ment (ex: ‘Th’) ou numĂ©ro atomique (ex: 90).

mononucleides(exclure_radiogeniques=True)[source]

Affiche les Ă©lĂ©ments mononuclĂ©idiques, c’est-Ă -dire possĂ©dant un seul isotope naturel (au sens de mendeleev : abundance non None).

Parameters:

exclure_radiogeniques (bool) – si True (par dĂ©faut), exclut les Ă©lĂ©ments comme le thorium, reclassĂ©s binuclĂ©idiques (ou plus) par l’IUPAC en 2013 Ă  cause d’isotopes radiogĂ©niques prĂ©sents en traces (voir TableauPeriodique.exceptionsRadiogeniques).

nomsFr = ['HydrogĂšne', 'HĂ©lium', 'Lithium', 'BĂ©ryllium', 'Bore', 'Carbone', 'Azote', 'OxygĂšne', 'Fluor', 'NĂ©on', 'Sodium', 'MagnĂ©sium', 'Aluminium', 'Silicium', 'Phosphore', 'Soufre', 'Chlore', 'Argon', 'Potassium', 'Calcium', 'Scandium', 'Titane', 'Vanadium', 'Chrome', 'ManganĂšse', 'Fer', 'Cobalt', 'Nickel', 'Cuivre', 'Zinc', 'Gallium', 'Germanium', 'Arsenic', 'SĂ©lĂ©nium', 'Brome', 'Krypton', 'Rubidium', 'Strontium', 'Yttrium', 'Zirconium', 'Niobium', 'MolybdĂšne', 'TechnĂ©tium', 'RuthĂ©nium', 'Rhodium', 'Palladium', 'Argent', 'Cadmium', 'Indium', 'Étain', 'Antimoine', 'Tellure', 'Iode', 'XĂ©non', 'CĂ©sium', 'Baryum', 'Lanthane', 'CĂ©rium', 'PrasĂ©odyme', 'NĂ©odyme', 'PromĂ©thium', 'Samarium', 'Europium', 'Gadolinium', 'Terbium', 'Dysprosium', 'Holmium', 'Erbium', 'Thulium', 'Ytterbium', 'Lutetium', 'Hafnium', 'Tantale', 'TungstĂšne', 'RhĂ©nium', 'Osmium', 'Iridium', 'Platine', 'Or', 'Mercure', 'Thallium', 'Plomb', 'Bismuth', 'Polonium', 'Astate', 'Radon', 'Francium', 'Radium', 'Actinium', 'Thorium', 'Protactinium', 'Uranium', 'Neptunium', 'Plutonium', 'Americium', 'Curium', 'Berkelium', 'Californium', 'Einsteinium', 'Fermium', 'Mendelevium', 'Nobelium', 'Lawrencium', 'Rutherfordium', 'Dubnium', 'Seaborgium', 'Bohrium', 'Hassium', 'Meitnerium', 'Darmstadtium', 'Roentgenium', 'Copernicium', 'Nihonium', 'Flerovium', 'Moscovium', 'Livermorium', 'Tennesse', 'Oganesson']
patch_elements()[source]

Ce patch, appliquĂ© Ă  self.elements, créé par l’appel Ă  create_vis_dataframe(), va servir Ă  : - corriger certaines classifications de familles (retire les Ă©lĂ©ments du groupe 12 de la

famille des métaux de transition, qui est le choix CONTESTABLE par défaut de mendeleev) ; cette partie est commune à TableauPeriodique et à sa sous-classe anglaise PeriodicTable

  • ajouter des informations localisĂ©es (noms des Ă©lĂ©ments et des familles) via self._localize_names(), surchargeable par une sous-classe

  • ajouter des donnĂ©es supplĂ©mentaires (Ă©nergie de premiĂšre ionisation) via self._ajouter_donnees()

input : elements est un dataframe pandas préalablement créé par la fonction create_vis_dataframe() de mendeleev.vis

output : elements avec les colonnes ajoutées par _localize_names() et _ajouter_donnees() + correction des données name_series et series_id pour les éléments Zn, Cd, Hg, Cn

prop(elt_id)[source]

Affiche les propriĂ©tĂ©s dĂ©taillĂ©es d’un Ă©lĂ©ment chimique.

Parameters:

elt_id (str ou int) – Symbole de l’élĂ©ment (ex: ‘O’) ou numĂ©ro atomique (ex: 8).

trad = {'Actinides': 'Actinide', 'Alkali metals': 'Métal alcalin', 'Alkaline earth metals': 'Métal alcalino-terreux', 'Halogens': 'HalogÚne', 'Lanthanides': 'Lanthanide', 'Metalloids': 'Métalloïde', 'Metals': 'Métal', 'Noble gases': 'Gaz noble', 'Nonmetals': 'Non métal', 'Poor metals': 'Métal pauvre', 'Transition metals': 'Métal de transition'}

pyphyschemtools.aithermo module

class pyphyschemtools.aithermo.aiThermo(folder_path=None, color_scales=None)[source]

Bases: object

A class to handle thermodynamic surface stability analysis and visualization within the tools4pyPhysChem framework. Initialize the aiThermo object.

Parameters:
  • folder_path (str or Path) – Path to the working directory.

  • color_scales (list, optional) – List of plotly-compatible color scales.

ListOfStableSurfaceCompositions(vib)[source]

Identify and list the relevant thermodynamic data files for the current analysis.

This method scans the working directory for data files matching specific naming conventions (TPcoverage or TPcoveragevib). It cross-references these with a local configuration file ‘ListOfStableSurfaces.dat’ to extract surface names and legend labels.

Parameters:

vib (bool) – If True, filters for files including vibrational corrections (prefixed with vib_). If False, looks for standard thermodynamic data.

Returns:

A triplet containing: - file_paths (list of str): Absolute or relative paths to the .dat files. - names (list of str): Internal identifiers for each surface phase. - legends (list of str): LaTeX-formatted or plain text labels for graphical legends.

Return type:

tuple

Notes

  • The lists are returned in reverse order to ensure correct layering during 3D plotting.

  • Relies on ‘ListOfStableSurfaces.dat’ existing in the folder_path.

plot_palette(angle=0, save_png=None)[source]

Visualize the 1D color palette used for surface identification.

This method generates a horizontal bar of colors corresponding to the different surface phases defined in the instance. Each color is labeled with its numerical index, allowing for quick cross-referencing between the palette and the 3D surface plot.

Parameters:
  • angle (int, optional) – Rotation angle of the x-axis tick labels (indices). Defaults to 0.

  • save_png (str, optional) – Filename (including .png extension) to save the palette image to the working directory. Defaults to None (display only).

Returns:

Displays the plot using matplotlib.pyplot.show().

Return type:

None

Notes

  • Requires ‘seaborn’ for the palplot generation.

  • If ‘save_png’ is provided, the image is saved with a resolution of 300 DPI and a transparent background.

plot_surface(saveFig=None, vib=True, texLegend=False, xLegend=0.5, yLegend=0.4)[source]

Generate an interactive 3D thermodynamic stability map using Plotly.

This method visualizes multiple Gibbs free energy surfaces as a function of Temperature (X) and Pressure (Y). It automatically handles log-scale transformations for the pressure axis and projects reference experimental conditions and phase boundaries onto the plot.

Parameters:
  • saveFig (str, optional) – The filename (without extension) to export the resulting plot as a PNG image. Defaults to None (no save).

  • vib (bool) – Whether to use vibration-corrected data. Defaults to True.

  • texLegend (bool) – If True, uses LaTeX legends extracted from the configuration file. Defaults to False.

  • xLegend (float) – Horizontal position of the legend box (0 to 1). Defaults to 0.5.

  • yLegend (float) – Vertical position of the legend box (0 to 1). Defaults to 0.4.

Returns:

An interactive widget containing

the 3D surfaces, experimental markers, and reference lines.

Return type:

plotly.graph_objects.FigureWidget

Workflow:
  1. Scans data files and parses Temperature/Pressure/Energy grids.

  2. Traces individual 3D surfaces with mapped color scales.

  3. Calculates and plots intersection boundaries between surface phases.

  4. Overlays experimental markers (e.g., specific T/P conditions).

  5. Optionally exports and crops the resulting image using Pillow.

pyphyschemtools.cheminformatics module

class pyphyschemtools.cheminformatics.easy_rdkit(smiles, canonical=True, lang='En')[source]

Bases: object

A helper class to analyze and visualize molecules using RDKit. Provides tools for Lewis structure analysis and advanced 2D drawing. Initialize the molecule object from a SMILES string.

Parameters:
  • smiles (str) – The SMILES representation of the molecule.

  • canonical (bool) – If True, converts the SMILES to its canonical form to ensure consistent atom numbering and uniqueness.

  • lang (str) – Language for headers and messages of the Lewis analyzis(“En” (default) or “Fr”).

analyze_lewis(heavy_only=True)[source]

Performs a simplified Lewis-structure analysis of the molecule, atom by atom, based on RDKit’s valence/bond perception (no 3D geometry involved).

For each atom, derives:
  • valence electrons (from the periodic table)

  • bonding electrons (RDKit’s total valence)

  • formal charge

  • lone pairs (nonbonding electrons / 2)

  • vacancies (missing electrons to reach octet/duet, if any)

  • total electron count and whether the octet (or duet, for H/He) rule is satisfied, electron-deficient, or hypervalent

This is a teaching aid, not a rigorous electronic-structure calculation: it relies on RDKit’s bond-order perception from the SMILES, so it reflects whatever Lewis structure RDKit infers and will not be meaningful for molecules with unusual/ambiguous valence (e.g. hypervalent or radical species) beyond the simple flags above.

Parameters:

heavy_only (bool) – If True (default), only heavy atoms (Z > 2) get a row in the returned table. H atoms are checked for duet compliance on an internal copy of the molecule with explicit Hs (self.mol itself is not modified), and a single summary line is printed after the table (✅ if all H satisfy the duet rule, ❌ with the offending atom indices otherwise). If False, H/He atoms are included in the table with full LP/vacancy detail, like heavy atoms.

Returns:

One row per analyzed atom, with columns depending on self.lang (“En”: Atom Index, Symbol, Valence e-, Bonding e-, Formal Charge, Lone Pairs (LP), Vacancies ([]), Number of Bonds, Total e- (octet?), Octet Status (O/H/D); “Fr”: French equivalents). H/He atoms are excluded from the rows when heavy_only is True.

Return type:

pd.DataFrame

Raises:
  • ValueError – if self.mol is None (invalid SMILES), with a message

  • in English or French depending on self.lang. –

analyze_stereochemistry()[source]

Summarizes the stereochemical features of the molecule as currently perceived by RDKit (chiral centers and stereogenic double bonds).

Unlike get_isomers, this does not enumerate alternative configurations — it only reports what is already encoded (or left unassigned, i.e. “?”) in self.mol.

Returns:

Dictionary with keys chiral_centers_count (int), chiral_centers (list of (atom_index, “R”/”S”/”?”)), stereo_bonds_count (int), and stereo_bonds (list of (begin_atom_idx, end_atom_idx, “STEREOE”/”STEREOZ”/
)).

Return type:

dict

property descriptors

Computes (once, then caches) a set of standard molecular descriptors.

Returns:

MW, LogP, QED, HBA, HBD, RotB (rotatable bonds), TPSA, aromatic/non-aromatic ring counts, Fsp3, and connectivity indices (Chi0, Chi1). Values are rounded for display.

Return type:

dict

Note

Computed lazily on first access and cached in self._descriptors_cache; if self.mol changes afterward (e.g. via show_mol adding explicit Hs), the cache is NOT automatically invalidated — delete self._descriptors_cache if you need a refresh.

static draw_consistent_svg(smiles_list, legends=None, size_per_mol=300, mols_per_row=3, bond_length=35.0, bond_width=1.2, font_size=12, save_img='export/molecules.svg')[source]

Generates an SVG file with a grid of molecules having consistent bond lengths. Ideal for high-quality printing and comparison.

Parameters:
  • smiles_list (list) – List of SMILES strings to draw.

  • legends (list, optional) – List of strings to display under each molecule.

  • size_per_mol (int) – Size of the square panel for each molecule (Default: 300).

  • mols_per_row (int) – Number of molecules per row (Default: 3).

  • bond_length (float) – Fixed length for bonds in pixels (Default: 35.0).

  • bond_width (float) – Thickness of the bonds (Default: 1.2).

  • font_size (int) – Font size for atom labels (Default: 12).

  • save_img (str) – Output SVG file path (Default: “export/molecules.svg”).

fetch_pubchem_data()[source]

Queries PubChem using the molecule’s current SMILES to retrieve its PubChem CID and IUPAC name, and stores them on the instance (self.cid, self.iupac_name).

This is the reverse of from_cid: instead of building the molecule from a known CID, it looks up an already-built molecule (e.g. created via easy_rdkit(“CCO”)) to see if it exists in PubChem.

Only the first match returned by PubChem is used. If the SMILES is ambiguous (e.g. corresponds to several close PubChem entries such as tautomers or salts), this may not be the expected compound — check self.cid against the PubChem page if in doubt.

Notes

  • Requires an internet connection (PubChem REST API via pubchempy).

  • Does not raise on failure: if no match is found, or if the request fails, a warning/error is printed and self.cid / self.iupac_name are left unchanged.

classmethod from_cid(cid, canonical=True, lang='En')[source]

Builds an easy_rdkit instance directly from a PubChem CID.

Fetches the compound from PubChem, extracts its connectivity SMILES, and uses it to construct the molecule (equivalent to easy_rdkit(smiles) but starting from a known CID instead). self.cid and self.iupac_name are set from the PubChem record.

Parameters:
  • cid (int or str) – The PubChem Compound ID.

  • canonical (bool) – Passed through to __init__.

  • lang (str) – Passed through to __init__ (“En” or “Fr”).

Returns:

The constructed instance.

Return type:

easy_rdkit

Raises:
  • ValueError – if the CID does not correspond to a valid PubChem compound.

  • ConnectionError – if the PubChem request fails (network/API issue).

classmethod from_name(name, canonical=True, lang='En')[source]

Builds an easy_rdkit instance directly from a compound name, by querying PubChem (e.g. “aspirin”, “caffeine”, “benzene”).

Parameters:
  • name (str) – Compound name to search for on PubChem.

  • canonical (bool) – Passed through to __init__.

  • lang (str) – Passed through to __init__ (“En” or “Fr”).

Returns:

The constructed instance, with self.cid and self.iupac_name set from the first PubChem match.

Return type:

easy_rdkit

Raises:
  • ValueError – if no PubChem compound matches the given name.

  • ConnectionError – if the PubChem request fails (network/API issue).

Note

If several compounds match the name, only the first PubChem result is used — check self.cid if the match seems ambiguous.

get_isomers(max_isomers=12, verbose=True)[source]

Explores the stereochemical space of the molecule by enumerating all possible stereoisomers.

This method identifies all unassigned or flexible stereocenters (chiral centers and double bonds) and generates a complete set of discrete stereochemical configurations. It is particularly useful for resolving “flat” SMILES strings into their constituent enantiomers and diastereomers.

Parameters:
  • max_isomers (int) – The maximum number of isomers to generate. This prevents computational explosion for molecules with many stereocenters (2^n). Defaults to 12.

  • verbose (bool) – If True, prints a summary of the number of isomers found using a colored terminal message. Defaults to True.

Returns:

A list of easy_rdkit instances, each representing a unique,

fully-defined stereoisomer of the parent molecule.

Return type:

list

static plot_grid_from_df(df, smiles_col='SMILES', legend_cols='IUPAC Name', mols_per_row=4, size=(250, 250), show_stereo=False, save_img=None)[source]

Generates a grid image of molecular structures from a pandas DataFrame.

This method extracts SMILES strings from the specified column, generates 2D representations, and arranges them in a grid. It supports multi-line legends by passing a list of column names, and can export the result to external files.

Parameters:
  • df (pd.DataFrame) – DataFrame containing the molecular data.

  • smiles_col (str) – Name of the column containing SMILES strings. Defaults to ‘SMILES’.

  • legend_cols (str or list) – Column name(s) to display as legends below each molecule. If a list is provided, each value is displayed on a new line (e.g., [‘IUPAC Name’, ‘MW’, ‘LogP’]). Defaults to ‘IUPAC Name’.

  • mols_per_row (int) – Number of molecules to display in each row. Defaults to 4.

  • size (tuple) – Dimensions (width, height) in pixels for each individual molecule panel. Defaults to (250, 250).

  • save_img (str, optional) – File path to save the resulting image. Supports ‘.svg’ (vector) and ‘.png’ (raster) extensions. Defaults to None.

Returns:

An SVG object for rich display in Jupyter/Colab environments.

Return type:

IPython.display.SVG

Note

PNG export requires the Cairo backend to be available in the RDKit installation.

show_descriptors()[source]

Prints the molecular descriptors (see descriptors) as a simple formatted table to stdout. Display-only; returns nothing.

show_isomers(mols_per_row=4, size=(250, 250), save_img=None)[source]

Generates, labels, and displays a grid of all possible stereoisomers.

This method automates the transition from a single chemical identity to a visual comparative analysis of its stereoisomers. Each isomer is rendered with its specific SMILES string (including @ markers and / directionals) and an isomer index. It utilizes the class’s internal grid-plotting logic to ensure high-quality SVG output and optional file export.

Parameters:
  • mols_per_row (int) – Number of isomer structures to display per row in the grid. Defaults to 4.

  • size (tuple) – The (width, height) in pixels for each individual molecular panel. Defaults to (250, 250).

  • save_img (str, optional) – File path (e.g., ‘isomers.svg’ or ‘isomers.png’) to export the grid. Directories are created automatically. Defaults to None.

Returns:

A grid image displayed directly in the Jupyter/Colab

environment.

Return type:

IPython.display.SVG

show_mol(size: tuple = (400, 400), show_Lewis: bool = False, plot_conjugation: bool = False, plot_aromatic: bool = False, show_n: bool = False, show_hybrid: bool = False, show_H: bool = False, show_stereo: bool = False, rep3D: bool = False, macrocycle: bool = False, highlightAtoms: list = [], legend: str = '', save_img: str = None)[source]

Renders the molecule as a 2D (SVG or PNG) depiction, with optional annotations, and displays it inline (Jupyter/Colab). Can also save the image to disk.

This is the main “do everything” drawing method of the class: most arguments toggle an independent overlay or computation that gets combined onto the same drawing. A few interactions to know about:

  • show_Lewis implies show_H (explicit Hs are added so lone pairs/ vacancies can be computed and displayed) and internally calls analyze_lewis(), which also prints/displays its DataFrame.

  • show_Lewis and show_hybrid share the same atom-note area (the little text under each atom); both can be shown together.

  • rep3D adds explicit Hs and computes a 3D-like embedding (AllChem.EmbedMolecule) before generating a (still 2D) drawing from it — mainly useful to get a more realistic bond geometry.

  • plot_conjugation and plot_aromatic each highlight bonds/atoms in a different color (blue / red) but use the same highlighting machinery, so combining both silently uses whichever was computed last (not an additive overlay).

  • show_stereo perceives and labels R/S and E/Z. If any chiral center or double bond is unassigned (“?”), it prints a warning and automatically turns on atom (and, for double bonds, bond) index display so you can identify what needs fixing in the SMILES.

  • Side effect: several options (show_H, show_Lewis, rep3D, macrocycle) mutate self.mol in place (adding Hs, 3D coords, atom notes), so self.mol may differ after calling show_mol even without save_img.

Parameters:
  • size (tuple) – Drawing dimensions in pixels (width, height).

  • show_Lewis (bool) – Annotate atoms with lone pairs / vacancies (implies show_H; runs analyze_lewis() and displays its table).

  • plot_conjugation (bool) – Highlight conjugated bonds in blue.

  • plot_aromatic (bool) – Highlight aromatic atoms/bonds in red.

  • show_n (bool) – Display atom indices.

  • show_hybrid (bool) – Display atom hybridization (sp, sp2, sp3
).

  • show_H (bool) – Add explicit hydrogens to the drawing.

  • show_stereo (bool) – Compute and display R/S, E/Z labels; warns and auto-enables index display if stereochemistry is undefined in the input SMILES.

  • rep3D (bool) – Embed a 3D-like conformation (via AllChem) before drawing, for more realistic bond angles.

  • macrocycle (bool) – Use CoordGen for better layout of large rings (e.g. cyclodextrins).

  • highlightAtoms (list) – Atom indices to highlight (ignored if plot_conjugation or plot_aromatic is used).

  • legend (str) – Caption displayed under the structure.

  • save_img (str, optional) – Output file path; extension decides format (‘.svg’ or ‘.png’). Image is also always displayed inline regardless of this argument.

Returns:

None. Displays the image (IPython.display.SVG) as a side effect; if save_img ends in ‘.png’, also regenerates and displays an SVG version for screen viewing (via a recursive call).

to_dict(auto_fetch=False)[source]

Exports identity and descriptors as a flat dictionary, ready for use in a DataFrame row (e.g. with plot_grid_from_df).

Parameters:

auto_fetch (bool) – If True and self.cid is not already set, calls fetch_pubchem_data() first to try to retrieve the CID/IUPAC name before building the dictionary.

Returns:

{“IUPAC Name”, “CID”, “SMILES”} plus all keys from descriptors (MW, LogP, QED, 
). CID/IUPAC Name are “N/A” if unavailable.

Return type:

dict

pyphyschemtools.core module

pyphyschemtools.core.centerTitle(content=None)[source]
pyphyschemtools.core.centertxt(content=None, style=None, font=None, size=None, weight=None, bgc=None, fgc=None)[source]

Centers and renders text as HTML in the notebook.

input:

  • content = text to render (default: None)

  • style = predefined style name (default: None). See STYLES below; any explicit parameter overrides the style.

  • font = font family (default: ‘sans’)

  • size = font size in px (default: 12)

  • weight = font weight (default: ‘normal’)

  • bgc = background color, name or hex (default: ‘#ffffff’)

  • fgc = foreground color, name or hex (default: ‘#000000’)

pyphyschemtools.core.crop_images(input_files, process_folder=False)[source]

Trims whitespace or transparency from image files and saves the results.

If process_folder is True, input_files is treated as a directory path, and all images within (excluding those ending in -C) are processed. Otherwise, input_files is treated as a single file path or a list of paths.

The function preserves original image metadata (DPI, ICC profiles).

Parameters:
  • input_files (str, Path, or list) – File path(s) or a directory path.

  • process_folder (bool) – If True, treats input_files as a directory to crawl.

Returns:

Prints status messages to the console for each file processed.

Return type:

None

pyphyschemtools.core.get_qc_examples(suite=None)[source]

Copies QC examples archive to the current directory. Supports terminal CLI (with help) and direct Python calls.

pyphyschemtools.core.save_data(df, path_with_name: str, **kwargs)[source]

Saves a Pandas DataFrame to CSV or Excel, automatically creating missing directories.

Parameters:
  • df (pd.DataFrame) – The DataFrame to save.

  • path_with_name (str) – The path and filename (e.g., “data/results.csv”).

  • **kwargs – Additional arguments passed to to_csv or to_excel (e.g., index=True).

pyphyschemtools.core.save_fig(path_with_name: str, fig=None, dpi: int = 300, **kwargs)[source]

Saves a figure to a path, automatically creating missing directories. Works with the current plt or a specific figure object.

Parameters:
  • path_with_name (str) – The path and filename (e.g., “results/plots/energy.svg”).

  • fig (matplotlib.figure.Figure, optional) – A specific figure object. If None, uses plt.gcf().

  • dpi (int) – Resolution for raster formats. Defaults to 300.

  • **kwargs – Additional arguments passed to savefig (e.g., transparent=True).

pyphyschemtools.core.smart_trim(img)[source]

Determines the bounding box of the meaningful content in an image.

This function automatically detects if the image has transparency (Alpha channel). If it does, it calculates the bounding box based on non-transparent pixels. If the image is opaque, it assumes a white background and calculates the bounding box by detecting differences from a pure white canvas.

Parameters:

img (PIL.Image.Image) – The source image object.

Returns:

A 4-tuple (left, upper, right, lower) defining the crop box,

or None if the image is uniform/empty.

Return type:

tuple

pyphyschemtools.huckel module

huckel.py

Simple HĂŒckel (HMO) method applied to molecules described by a SMILES string, with Streitwieser parametrization for heteroatoms.

Overview

  1. Start from a complete SMILES (sigma skeleton + pi system).

  2. RDKit identifies the atoms belonging to the conjugated pi system (aromatic atoms, plus atoms linked by non-aromatic conjugated bonds: dienes, enones, etc.).

  3. Each pi atom is given a Coulomb parameter h_X and each pi bond a resonance parameter k_C-X (Streitwieser), relative to the reference values alpha_C and beta_CC:

    alpha_X = alpha_C + h_X * beta_CC
    beta_CX = k_CX   * beta_CC
    

    Automatic detection (degree, number of H atoms, aromaticity) picks the heteroatom type (pyridine-like/pyrrole-like N, ether/furan or carbonyl O, etc.); the caller can always override these values with h_overrides / k_overrides / electron_overrides.

  4. The HĂŒckel matrix is diagonalized, the MOs are filled by the Aufbau principle (+ Hund’s rule for degenerate levels), and a number of diagrams / descriptors can be derived from the result: the energy diagram, MO coefficients drawn on the real 2D geometry of the molecule, frontier-orbital (HOMO/LUMO) figures, pi charges and pi bond orders, the density matrix, and reactivity descriptors (HOMO/LUMO energies, hardness, electronegativity
).

Limitations: pure pi-electron model, no explicit self-consistency (no extended HĂŒckel, no charge-dependent VSIP); formal charge only enters through its effect on the number of pi electrons contributed by each atom.

class pyphyschemtools.huckel.HMO(smiles: str, h_overrides: dict[int, float] | None = None, k_overrides: dict[int, float] | None = None, electron_overrides: dict[int, int] | None = None, charge: int = 0, parameter_set: str = 'van_catledge', include_hyperconjugation: bool = True, alkyl_scope: str = 'all', include_halogen_lone_pairs: bool = True)[source]

Bases: object

HĂŒckel pi system built from a SMILES string.

Parameters:
  • smiles (str) – SMILES of the complete molecule (sigma skeleton + pi system).

  • h_overrides (dict[int, float], optional) – Force h_X for the given RDKit atom index, or k_C-X for the pi bond(s) touching that atom (key = index of one of the two atoms of the bond; use a (i, j) tuple key to target one specific bond).

  • k_overrides (dict[int, float], optional) – Force h_X for the given RDKit atom index, or k_C-X for the pi bond(s) touching that atom (key = index of one of the two atoms of the bond; use a (i, j) tuple key to target one specific bond).

  • electron_overrides (dict[int, int], optional) – Force the number of pi electrons contributed by the given atom index.

  • charge (int, optional) – Defaults to 0. A global formal charge added to the WHOLE pi system, on top of whatever individual atoms already contribute – the easy way to study a system-wide reduction/oxidation (e.g. the benzene dication, HMO(“c1ccccc1”, charge=2), or the naphthalene dianion, HMO(“c1ccc2ccccc2c1”, charge=-2)) WITHOUT having to spell out a carbocation/carbanion center anywhere in the SMILES (which – see _detect_pi_system – also ties that extra/missing electron to one particular atom, rather than letting it delocalize over the whole system the way a real, symmetric di-ion does). Ordinary chemistry sign convention: a positive charge REMOVES that many pi electrons (cation), a negative one ADDS that many (anion); pi_charge’s per-atom values still sum to exactly this charge however it ends up delocalized.

  • parameter_set (str, optional) – “van_catledge” (default) or “streitwieser” – which one-/two- center parameter table to use for heteroatoms (see parameter_table). “van_catledge” additionally covers B, Si and P, defines a full heteroatom-heteroatom k_XY matrix (Streitwieser only tabulates k_C-X), and enables free_valence.

  • include_hyperconjugation (bool, optional) – Defaults to True. A methyl or alkyl group attached directly to the conjugated system (e.g. toluene’s -CH3, or a benzylic -CH2- of indane/tetralin) is included as one extra pseudo-heteroatom contributing a lone pair (Matsen’s and Stevenson’s “heteroatom model” of hyperconjugation, (sym, kind)=(“C”, “methyl_donor”) – see STREITWIESER_TABLE / VAN_CATLEDGE_TABLE), the whole substituent collapsed to its FIRST attached carbon only (its own further substitution, e.g. the rest of an ethyl or isopropyl group, is not modeled any further). Only a substituent with exactly ONE attachment point to the conjugated system qualifies – a -CH2- bridging two separate pi systems is left alone, as a genuine break in conjugation, not a substituent. The literature value (h=2.0, k=0.7) is strictly only derived for a true methyl; for any larger alkyl it is reused as the closest available approximation, and a warning is raised naming the atom (see alkyl_scope to restrict this to true methyls only, or pass h_overrides/k_overrides/electron_overrides for that atom index to supply a better value by hand). Set to False to restore the previous behavior (these substituents are plain, inert sigma groups, outside the pi system entirely).

  • alkyl_scope (str, optional) – “all” (default) or “methyl_only” – with include_hyperconjugation, whether a larger alkyl substituent (-CH2R, -CHR2, -CR3) is included too (reusing the methyl parameter, with a warning) or only a true methyl (-CH3) is. Ignored if include_hyperconjugation=False.

  • include_halogen_lone_pairs (bool, optional) – Defaults to True. A halogen (F, Cl or Br) attached directly to the conjugated system (e.g. fluorobenzene’s -F, vinyl chloride’s -Cl) is included in the pi system as one extra 2-electron lone-pair donor, parametrized exactly like any other heteroatom (see STREITWIESER_TABLE / VAN_CATLEDGE_TABLE, (symbol, “halogen”)) – the standard HĂŒckel textbook treatment of aryl/vinyl halides. This is genuinely RDKit’s own blind spot (its GetIsConjugated() is also False for an aryl/vinyl- halogen bond, the same class of issue as the ethylene/allyl cases documented in _detect_pi_system), yet whether to model a halogen’s lone pair at all is a modelling CHOICE rather than an unambiguous correction – some HĂŒckel treatments leave halogens out entirely. A UserWarning is raised for every halogen folded in this way, naming the atom. Set to False to restore the previous behavior (halogens left out, as plain, inert sigma substituents, outside the pi system entirely).

atomization_energy(alpha: float = 0.0, beta: float = 1.0) → float[source]

HĂŒckel atomization (delocalization) energy:

Eat = E_pi(HĂŒckel) - sum_r (alpha_r * contributed_r)

i.e. the total pi-electron energy of the real, delocalized molecule minus the reference energy of the same pi electrons sitting, non-interacting, on their own atoms (each atom r contributing contributed_r electrons at its own Coulomb level alpha_r = alpha + h_r * beta).

Same dimensionless “units of |beta|” convention as total_pi_energy by default (alpha=0, beta=+1, i.e. beta’s magnitude): a positive Eat means the delocalized pi system is more stable than the isolated-atom reference (the usual case: conjugation/aromatic stabilization). Pass the real, physically negative beta (e.g. in eV) for a true physical energy – the sign then flips, since a system that is MORE stable has a LOWER (more negative) energy once beta’s true sign is used.

input: - alpha = Coulomb reference energy (default: 0.0) - beta = resonance reference energy; magnitude convention by default – pass the real, physically negative value for a true physical energy (default: 1.0)

output: - atomization energy Eat, in the chosen alpha/beta units

bond_order(r: int, s: int) → float[source]

Pi bond order between local pi-atom indices r and s (same indexing as self.labels / self.c_MOs rows):

p_rs = sum_i n_i * c_ri * c_si

input: - r = local pi-atom index (row of self.c_MOs) - s = local pi-atom index (row of self.c_MOs)

output: - the pi bond order p_rs between atoms r and s

conjugation_energy(alpha: float = 0.0, beta: float = 1.0) → float[source]

HĂŒckel conjugation (resonance/delocalization) energy, relative to a LOCALIZED (Kekule) reference structure rather than to fully isolated atoms:

Econj = E_pi(HĂŒckel) - [ sum over formal pi double bonds of
                            2*(localized bonding level)
                          + sum over unpaired atoms of
                            (contributed_r * alpha_r) ]

This is the classic textbook quantity (e.g. “benzene’s resonance energy is 2|beta|”): each formal double bond of a Kekule structure (from a Kekulized copy of the input SMILES, see _kekule_pairing) is treated as its own isolated, localized 2-center pi bond – diagonalizing just that 2x2 block (which reduces to the familiar alpha+beta level for a plain C=C, but generalizes correctly to a heteroatom-involving double bond such as pyridine’s C=N, whose two atoms have different alpha) – and occupied with 2 electrons; an atom left unpaired by that Kekule structure (a lone pair localized on a single center: pyrrole- type N, furan-type O, a conjugated halogen, a hyperconjugating methyl/alkyl pseudo-atom, or a formally charged/radical center) keeps the same isolated-atom reference as atomization_energy.

Unlike atomization_energy (reference: fully isolated, non- interacting atoms, no bonding of any kind), this isolates only the stabilization gained by DELOCALIZING beyond simple, already- bonded, localized double bonds – the smaller, more specific number usually meant by “conjugation energy” or “resonance energy” in textbooks.

Same dimensionless “units of |beta|” convention as atomization_energy by default (alpha=0, beta=+1): a positive Econj means the delocalized pi system is more stable than its own localized Kekule structure.

input: - alpha = Coulomb reference energy (default: 0.0) - beta = resonance reference energy; magnitude convention by default – pass the real, physically negative value for a true physical energy (default: 1.0)

output: - conjugation energy Econj, in the chosen alpha/beta units

density_matrix(as_dataframe: bool = True)[source]

First-order pi density (charge/bond-order) matrix:

P = C . diag(n) . C^T

where C holds the MO coefficients (columns) and n the MO occupations. P_rr is the electron density on atom r, P_rs (r != s) is the pi bond order between atoms r and s.

Displayed immediately (works regardless of where this call sits in a cell – see show() for why) and cached as self.density_matrix_df; returns None (read the attribute, or call again, for the value itself).

input: - as_dataframe = if True (default), cache/display the matrix as a labeled pandas DataFrame; if False, as a plain numpy array

output: - None (the matrix is displayed and cached as self.density_matrix_df)

property electron_density: ndarray

Pi electron density per atom (local index, same order as self.labels): q_r = sum_i n_i * c_ri^2.

property free_valence: ndarray

Free valence (radical-reactivity) index per atom:

F_r = Fx_r - sum_s p_rs   (sum over the pi-bonded neighbours s)

where Fx_r is Van Catledge’s reference maximum total bond order for that atom’s type/hybridization (e.g. Fx=1.732=sqrt(3) for an ordinary sp2 carbon). A larger F_r means a more reactive site towards radical attack.

Only defined for parameter_set=”van_catledge” – the Streitwieser table does not provide reference Fx values. Reference: Van- Catledge, J. Org. Chem. 1980, 45 (24), 4801-4802 (Table I).

output: - free valence F_r per atom, as a numpy array (one value per pi atom, same order as self.labels)

huckel_matrix(symbolic: bool = False, as_dataframe: bool = True)[source]

The HĂŒckel matrix itself, such that H = alpha*I + beta*M.

symbolic=False (default): returns the numeric, dimensionless matrix M (diagonal = Coulomb parameters h_r, off-diagonal = resonance parameters k_rs for bonded pi atoms, 0 otherwise). For a simple all-carbon system (all h_r=0, all k_rs=1) this is just 0/1 – e.g. ethylene C=C gives [[0, 1], [1, 0]].

symbolic=True: returns the same matrix with literal Greek-letter alpha/beta entries instead of numbers – a diagonal entry is alpha when h_r=0, else alpha + h*beta with the numeric h_r substituted in; an off-diagonal bonded entry is beta when k_rs=1, else k*beta with the numeric k_rs substituted in; unbonded pairs are 0. Uses real sympy symbols (nicer, typeset rendering in Jupyter) if sympy is installed, otherwise plain Greek-letter strings (“α”, “α + 0.5·ÎČ”, 
).

Displayed immediately (works regardless of where this call sits in a cell – see show() for why) and cached as self.huckel_matrix_df – a labeled pandas DataFrame (rows/cols = self.labels) if as_dataframe=True and pandas is available, otherwise a raw numpy array (symbolic=False) or a list of lists (symbolic=True). Returns None (read the attribute, or call again, for the value itself).

mo_table(as_dataframe: bool = True, tol: float = 1e-06, with_coefficients: bool = True, coeff_tol: float = 1e-09)[source]

Table of all pi MOs (index, x in units of beta, occupation, role, and – by default – the MO coefficient on every pi atom), ordered from the least stable (top) to the most stable (bottom) MO – same order as the energy diagram. A degenerate HOMO or LUMO (several MOs sharing the same x) is fully reflected in the role column, not just a single representative MO. Values of x within tol of zero are cleaned up to exactly 0.0 (floating- point noise from the diagonalization), and likewise for the coefficients within coeff_tol.

with_coefficients=True (default) adds one column per pi atom (named after self.labels, e.g. “C0”, “N3”, 
) holding c_ri, the coefficient of that atom in MO i – set it to False for a compact table with just index/energy/occupation/role (this is what summary() uses, to keep the printed report short for large systems).

Displayed immediately (works regardless of where this call sits in a cell – see show() for why) and cached as self.mo_table_df – a pandas DataFrame if as_dataframe=True and pandas is available, otherwise a list of dicts. Returns None (read the attribute, or call again, for the value itself).

property pi_charge: ndarray

Net formal pi charge per atom = (pi electrons a NEUTRAL atom of that same type would contribute) - (electron density actually found there). Positive means electron-poor relative to the neutral reference, negative means electron-rich.

For almost every atom type this neutral reference IS contributed_pi_electrons (a neutral pyrrole-type N really does contribute 2, a neutral pyridine-type N really does contribute 1 – the heteroatom’s charge state, if any, is already encoded through h instead, e.g. (“N”,”pyridinium”) keeps n_pi=1, same as neutral pyridine). The one exception is a carbon folded into the pi system as (“C”,”anion”)/(“C”,”cation”) (e.g. the allyl/benzyl cation or anion, cyclopentadienyl anion, tropylium): contributed_pi_electrons is 2 or 0 there – the ion’s OWN electron count, needed elsewhere for n_pi_electrons – but the neutral reference used HERE is 1, same as any other carbon, so the molecule’s one formal charge unit is correctly spread over every position by the delocalization itself, instead of being double-counted (pre-paid once at that single atom’s reference, then distributed again by its density). This is why, e.g., tropylium comes out with +1/7 on EVERY carbon (by symmetry), never a spuriously negative nominal “+” center.

Sums to exactly the pi system’s total formal charge (0 for a neutral molecule; +1 for a cation such as tropylium or the allyl cation; -1 for an anion such as the cyclopentadienyl anion) – not always 0.

plot_all_mo(ncols=3, figsize_per=None, bond_length_px=70, save_path=None, dpi=300)[source]

Grid with every pi MO drawn on the molecular graph. See plot_mo_list for a grid restricted to a chosen subset of MOs (e.g. just the frontier ones, or a hand-picked list).

plot_energy_diagram(mode=None, ax=None, figsize=None, tol=1e-06, frontier_figsize=None, save_path=None, dpi=300)[source]

Energy-level diagram. The x axis is oriented so that the energy E = alpha + x*beta increases upward (beta < 0: the largest, most stabilizing x values end up at the bottom).

mode=”FMO” (or “fmo”): instead of the diagram alone, build and return a full figure with the diagram plus the HOMO(s)/LUMO(s) (frontier orbitals) next to it, so the subplots do not have to be composed by hand. Handles degenerate HOMO/LUMO sets and radical (SOMO) cases.

figsize defaults to None, which auto-scales the diagram’s width with the largest level degeneracy (e.g. benzene, max degeneracy 2, stays as compact as before; a highly degenerate spectrum such as C60’s, up to degeneracy 9, gets enough room for every individual segment) – pass an explicit figsize to override.

save_path: if given, the figure is also saved there (see save_fig); dpi is passed through.

input: - mo_index = index of the MO to draw (column of self.c_MOs) - ax = matplotlib Axes to draw on; a new figure is created if None (default) - scale = marker-size scale factor for the largest coefficient - figsize = (width, height) in inches; auto-computed from bond_length_px if None (default) and ax is None - bond_length_px = target on-screen bond length in pixels, used to auto-size figsize (default: 70) - lobe_offset = separation of the two lobes, as a fraction of each atom’s marker radius (default: 0.2); see above - save_path = file path to save the figure to (passed to save_fig); not saved if None (default) - dpi = resolution passed to save_fig when save_path is given (default: 300)

output: - None (the figure is drawn and shown, and saved if save_path is given)

plot_mo_list(mo_indices, ncols=3, figsize_per=None, bond_length_px=70, save_path=None, dpi=300)[source]

Grid with a chosen list of pi MOs drawn on the molecular geometry (see plot_mo_on_graph for a single one) – e.g. mol.plot_mo_list([0, 1, 7, 8]) to compare a few MOs of interest side by side, in exactly the order given, without plotting the whole set as plot_all_mo does.

figsize_per (the per-panel size) defaults to None, which auto-sizes EVERY panel, uniformly, from the molecule’s own 2D layout so a C-C bond renders at roughly bond_length_px screen pixels – same idea, and the same _figsize_for_bond_px helper, as the standalone plot_mo_on_graph’s own figsize/ bond_length_px (all panels here show the SAME molecule, just a different MO each, so one computed size applies to all of them). Pass an explicit figsize_per to override.

save_path: if given, the figure is also saved there (see save_fig); dpi is passed through.

input: - mo_index = index of the MO to draw (column of self.c_MOs) - ax = matplotlib Axes to draw on; a new figure is created if None (default) - scale = marker-size scale factor for the largest coefficient - figsize = (width, height) in inches; auto-computed from bond_length_px if None (default) and ax is None - bond_length_px = target on-screen bond length in pixels, used to auto-size figsize (default: 70) - lobe_offset = separation of the two lobes, as a fraction of each atom’s marker radius (default: 0.2); see above - save_path = file path to save the figure to (passed to save_fig); not saved if None (default) - dpi = resolution passed to save_fig when save_path is given (default: 300)

output: - None (the figure is drawn and shown, and saved if save_path is given)

plot_mo_on_graph(mo_index, ax=None, scale=800, figsize=None, bond_length_px=70, lobe_offset=0.2, save_path=None, dpi=300)[source]

Coefficients of MO mo_index drawn on the real 2D geometry of the molecule, each pi atom rendered as a stylized two-lobed p orbital rather than a flat disc: a front lobe (circle size = |c_i|, color = sign of c_i, same convention as before) shifted slightly toward the bottom-left along the diagonal, and a same- size, opposite-color back lobe shifted the same amount toward the top-right, drawn behind it. The atom label stays at the true atom position, between the two lobes.

figsize defaults to None, which auto-sizes the panel from the molecule’s own 2D layout so a C-C bond renders at roughly bond_length_px screen pixels (see _figsize_for_bond_px) – this is what keeps ethylene’s one short bond from filling the whole panel the way it would at a fixed figsize, while a much larger pi system (coronene
) still gets the room it needs; pass an explicit figsize to override. Only applies when this call creates its OWN figure (ax=None) – when composed into an existing ax (plot_all_mo/plot_mo_list/the frontier- orbital panels), the panel’s size is already decided by the caller instead.

lobe_offset: how far apart the two lobes are drawn, as a fraction of EACH atom’s own rendered circle radius (so a big coefficient’s lobes are offset more than a small one’s, and the two always overlap sensibly regardless of marker size) – 0 collapses back to a single disc per atom (the pre-existing look); 1 offsets each lobe by a full radius (touching at the atom’s true position); the default (0.2) gives a subtle, mostly-overlapping two-lobed look – raise it for a more pronounced dumbbell shape.

save_path: if given, the figure is also saved there (see save_fig); dpi is passed through.

input: - mo_index = index of the MO to draw (column of self.c_MOs) - ax = matplotlib Axes to draw on; a new figure is created if None (default) - scale = marker-size scale factor for the largest coefficient - figsize = (width, height) in inches; auto-computed from bond_length_px if None (default) and ax is None - bond_length_px = target on-screen bond length in pixels, used to auto-size figsize (default: 70) - lobe_offset = separation of the two lobes, as a fraction of each atom’s marker radius (default: 0.2); see above - save_path = file path to save the figure to (passed to save_fig); not saved if None (default) - dpi = resolution passed to save_fig when save_path is given (default: 300)

output: - None (the figure is drawn and shown, and saved if save_path is given)

plot_pi_population(ax=None, figsize=None, bond_length_px=100, charge_fmt='{:+.2f}', bond_fmt='{:.2f}', atom_fontsize=10, bond_fontsize=10, save_path=None, dpi=300)[source]

Classic HĂŒckel ‘charge and bond-order diagram’: the pi system graph annotated with the net pi charge on each atom and the pi bond order on each bond (see pi_charge / bond_order / density_matrix).

figsize defaults to None, which auto-sizes the figure from the molecule’s own 2D layout so a C-C bond renders at roughly bond_length_px screen pixels (see _figsize_for_bond_px) – larger than plot_mo_on_graph’s own default (100 vs. 70) since the bond-order labels sitting right on top of each bond need more room to stay legible than a plain p-orbital lobe does; pass an explicit figsize to override. atom_fontsize/ bond_fontsize control the label sizes directly – bump them further for a very crowded graph, or when exporting to a larger figure.

save_path: if given, the figure is also saved there (see save_fig); dpi is passed through.

input: - mo_index = index of the MO to draw (column of self.c_MOs) - ax = matplotlib Axes to draw on; a new figure is created if None (default) - scale = marker-size scale factor for the largest coefficient - figsize = (width, height) in inches; auto-computed from bond_length_px if None (default) and ax is None - bond_length_px = target on-screen bond length in pixels, used to auto-size figsize (default: 70) - lobe_offset = separation of the two lobes, as a fraction of each atom’s marker radius (default: 0.2); see above - save_path = file path to save the figure to (passed to save_fig); not saved if None (default) - dpi = resolution passed to save_fig when save_path is given (default: 300)

output: - None (the figure is drawn and shown, and saved if save_path is given)

properties(alpha: float = 0.0, beta: float = 1.0, as_series: bool = False)[source]

Frontier-orbital energies and simple conceptual-DFT reactivity descriptors, handy to collect into a table (DataFrame) across several molecules.

alpha/beta control E_HOMO, E_LUMO, gap, hardness, softness, chemical_potential, electronegativity and electrophilicity. They default to alpha=0, beta=+1: E_HOMO, E_LUMO, chemical_potential and electronegativity are then reported as their COEFFICIENT of beta (E = alpha + value*beta), the same convention as mo_table (x_beta) – e.g. E_HOMO = 0.618 means alpha + 0.618*beta. gap, hardness and electrophilicity are intrinsically positive quantities and are always returned as positive values, in units of |beta| (softness in 1/|beta|). Pass the real, physically negative beta (e.g. in eV) to get all of these in physical units.

total_pi_energy, atomization_energy and conjugation_energy are NOT affected by alpha/beta here – they are always reported in the dimensionless “units of |beta|” convention (beta’s magnitude, always positive for a normal bonded pi system; see total_pi_energy/atomization_energy/conjugation_energy, or self.E_total / self.E_atomization / self.E_conjugation). Call those methods directly, with your own alpha/beta, for a physical-unit total/atomization/conjugation energy.

input: - alpha = Coulomb reference energy (default: 0.0) - beta = resonance reference energy; dimensionless magnitude convention by default – pass the real, physically negative value (e.g. in eV) for physical units (default: 1.0) - as_series = if True, return a pandas Series instead of a dict (requires pandas); default: False

output: - dict (or pandas Series if as_series=True) with: smiles, n_pi_atoms, n_pi_electrons, homo_index, lumo_index, E_HOMO, E_LUMO, gap, hardness, softness, chemical_potential, electronegativity, electrophilicity, total_pi_energy, atomization_energy, conjugation_energy

save_results(path_with_name: str, tol: float = 1e-06, **kwargs)[source]

Save the MO table (with coefficients) and the density matrix together in one multi-sheet Excel/ODS file (one sheet each: “MO”, “density_matrix”), via pandas.ExcelWriter – the engine (openpyxl for .xlsx, odfpy for .ods) is picked automatically from the file extension, and must be installed. For a single table (e.g. properties_table’s own result), just call the module-level save_data(df, path) directly instead.

tol: passed to the MO table (numerical cleanup of near-zero values – not the coefficient tolerance, which keeps its own default; pass coeff_tol via a direct mo_table() call if you need to change that one too).

Computes the two tables directly (rather than going through mo_table/density_matrix) so saving a file stays silent – those public methods now always display their result immediately, which isn’t wanted here. Both tables are still cached as self.mo_table_df/self.density_matrix_df, same as calling each method would.

show(ax=None, figsize=None, size=None, bond_length_px=80, title=None, show_indices=True, show_hybridization=False, highlight_pi=True, save_path=None, dpi=300)[source]

Draw the molecule’s FULL 2D skeleton (sigma + pi, with implicit H’s, wedge/dash stereo if any
) using RDKit’s own depiction engine – unlike plot_mo_on_graph / plot_pi_population, which only draw the pi subsystem detected for the HĂŒckel treatment. Handy as a quick sanity check that the SMILES was parsed/drawn (and the conjugated system detected) as intended.

show_indices (default True): label each atom with its RDKit atom index – the same index used in self.pi_atom_idx and in the “C0”, “N3”
 entries of self.labels. show_hybridization: annotate each atom with its hybridization (sp, sp2, sp3
) as given by RDKit. highlight_pi (default True): highlight the atoms/bonds of the conjugated pi system actually used for the HĂŒckel treatment (self.pi_atom_idx) – the rest of the molecule (sigma-only substituents, sp3 carbons
) is left unhighlighted.

size defaults to None, which sizes RDKit’s own drawing canvas from the molecule’s actual 2D layout (its full sigma+pi skeleton, not just the pi system) so a C-C bond renders at a FIXED bond_length_px (80 by default) – RDKit’s own fixedBondLength drawing option (verified empirically: it is NOT a 1:1 pixel setting on this RDKit build, so the conversion is calibrated against _bond_unit_length). This is what keeps ethylene’s one bond from filling the whole canvas the way a fixed size would, while a large, crowded molecule (coronene
) still gets a canvas sized to actually fit it, hybridization labels and all. Pass an explicit size (pixels, RDKit’s own legacy behavior: the molecule is auto-scaled, in either direction, to fill that fixed canvas) to go back to a plain fixed-size drawing instead – bond_length_px is then ignored. The drawing’s blank margin is cropped automatically either way.

figsize defaults to None, which sizes the matplotlib figure to match the (now-cropped) drawing 1:1 in pixels when size was auto-computed (so the bond-length guarantee above survives all the way to the actual on-screen rendering, not just the intermediate RDKit image), or to the drawing’s aspect ratio at a fixed 4-inch height when an explicit size was given instead (the previous behavior). Pass an explicit figsize to override either way (e.g. to make it larger, or to match a figure you’re composing by hand). title defaults to the SMILES. save_path/dpi: see save_fig.

summary()[source]

Print a short text report: SMILES, pi atoms (with the number of pi electrons each one contributes), total pi electrons, total HĂŒckel pi-energy, atomization energy, conjugation (Kekule- referenced resonance) energy, and the full MO table (see mo_table to get it as a DataFrame instead of printed text).

total_pi_energy(alpha: float = 0.0, beta: float = 1.0) → float[source]

Total HĂŒckel pi-electron energy:

E_pi = sum_i n_i * (alpha + x_i * beta)

where n_i is the occupation of MO i and x_i its coefficient (self.E_MOs). Defaults to the dimensionless “units of |beta|” convention used when quoting these energies in textbooks (e.g. “E_pi(benzene) = 6*alpha + 8*beta”): alpha=0, beta=+1 – the magnitude of beta, reported as a plain coefficient, not beta’s true physical sign. Since the lowest-energy (most bonding) MOs are filled first and have the largest x, this dimensionless total is positive for any normal bonded pi system. Pass the real, physically negative beta (e.g. in eV) to get the true, physical (and then negative) energy.

input: - alpha = Coulomb reference energy (default: 0.0) - beta = resonance reference energy; magnitude convention by default – pass the real, physically negative value for a true physical energy (default: 1.0)

output: - total pi-electron energy E_pi, in the chosen alpha/beta units

used_parameters(as_dataframe: bool = True)[source]

The parameter-table rows actually used for the atom classes present in THIS molecule – a convenient subset of parameter_table(self.parameter_set) to sanity-check what was applied (one row per distinct (symbol, kind), in the order first encountered). Each row also repeats self.parameter_set (so the table is self-identifying – “streitwieser” or “van_catledge” today, whatever other parameter sets may be added later – even when read out of context, e.g. printed on its own or saved to a file).

Displayed immediately (works regardless of where this call sits in a cell – see show() for why) and cached as self.used_parameters_df – a pandas DataFrame if as_dataframe=True and pandas is available, otherwise a list of dicts. Returns None (read the attribute, or call again, for the value itself).

pyphyschemtools.huckel.hmo_properties_table(smiles_list, alpha: float = 0.0, beta: float = 1.0, **huckel_kwargs)[source]

Build a table of frontier-orbital descriptors (see HMO.properties) for a list of molecules, ready to use as a pandas DataFrame.

Parameters:
  • smiles_list (list) – Each element is either a bare SMILES string, or a (smiles, overrides_dict) tuple for per-molecule keyword overrides (h_overrides, k_overrides, electron_overrides, charge).

  • alpha (float) – Passed to HMO.properties for every molecule.

  • beta (float) – Passed to HMO.properties for every molecule.

  • **huckel_kwargs – Default keyword arguments passed to every HMO(
) construction (overridden per-molecule by the tuple form above).

  • available (Returns a pandas DataFrame if pandas is)

  • list (otherwise a)

  • dicts. (of)

pyphyschemtools.huckel.parameter_table(parameter_set: str = 'van_catledge', as_dataframe: bool = True)[source]

The full one-center HĂŒckel parameter table for parameter_set (“streitwieser” or “van_catledge”): one row per (symbol, kind) with its h, k_to_carbon and n_pi_electrons, plus Fx (reference free valence) for “van_catledge” (Streitwieser does not define one).

Returns a pandas DataFrame if as_dataframe=True and pandas is available, otherwise a list of dicts.

References

streitwieser: A. Streitwieser, Jr., “Molecular Orbital Theory for

Organic Chemists”, John Wiley & Sons, 1961, p. 135.

van_catledge: F. A. Van-Catledge, “A Pariser-Parr-Pople-Based Set of

HĂŒckel Molecular Orbital Parameters”, J. Org. Chem. 1980, 45 (24), 4801-4802.

pyphyschemtools.huckel.save_data(df, path_with_name: str, **kwargs)[source]

Saves a Pandas DataFrame to CSV or Excel, automatically creating missing directories.

Parameters:
  • df (pd.DataFrame) – The DataFrame to save.

  • path_with_name (str) – The path and filename (e.g., “data/results.csv”).

  • **kwargs – Additional arguments passed to to_csv or to_excel (e.g., index=True).

pyphyschemtools.huckel.save_fig(path_with_name: str, fig=None, dpi: int = 300, **kwargs)[source]

Saves a figure to a path, automatically creating missing directories. Works with the current plt or a specific figure object.

Parameters:
  • path_with_name (str) – The path and filename (e.g., “results/plots/energy.svg”).

  • fig (matplotlib.figure.Figure, optional) – A specific figure object. If None, uses plt.gcf().

  • dpi (int) – Resolution for raster formats. Defaults to 300.

  • **kwargs – Additional arguments passed to savefig (e.g., transparent=True).

pyphyschemtools.hydrogen module

hydrogen.py — hydrogen atom and hydrogenic ions

Bohr model / analytical solution of the Schrodinger equation for a one-electron system (H, He+, Li2+, 
), with an optional finite nuclear-mass (reduced-mass) correction.

Public functions: - rydberg_Z : Rydberg constant corrected for the reduced mass - En_hydrogenic : energy of level n (in joules) - Ei_hydrogenic : ionization energy (in eV)

pyphyschemtools.hydrogen.Ei_hydrogenic(Z, A=None, M_atom=None, reduced_mass=True)[source]

Ionization energy (in eV) of a hydrogenic (hydrogen-like) ion of nuclear charge Z, i.e. the energy to remove its single electron from the ground state (n=1 to infinity). Ei = h*c*R*Z^2, the opposite of the ground-state energy.

input:

  • Z = nuclear charge / atomic number (1 = H, 2 = He+, 3 = Li2+, 
)

  • A = mass number of the isotope (for the mendeleev mass lookup)

  • M_atom = atomic mass in kg (overrides the lookup)

  • reduced_mass = if True (default), R = R_M is corrected for the finite nuclear mass of the isotope (see rydberg_Z); if False, R = Rinf is the infinite-nucleus limit (A and M_atom are then ignored)

output:

  • ionization energy of the hydrogen-like ion, in eV

note: this is a non-relativistic Bohr/Schrodinger result. The reduced-mass correction is tiny (~1e-4 relative) and shrinks as Z grows, whereas the gap to experiment grows with Z because relativistic and QED effects (absent here) scale steeply with Z. To compare with mendeleev, the Z-th ionization energy of the element matches the hydrogen-like ion of charge Z.

pyphyschemtools.hydrogen.En_hydrogenic(n, Z=1, A=None, M_atom=None, reduced_mass=True, unit='eV')[source]

Energy of level n of a hydrogenic (hydrogen-like) atom or ion (Bohr model / analytical solution of the Schrodinger equation), in joules or eV.

E_n = -h*c*R * Z^2 / n^2, with R the Rydberg constant. With reduced_mass=True (default) R = R_M is corrected for the finite nuclear mass of the isotope (see rydberg_Z); with reduced_mass=False R = Rinf is the infinite-nucleus limit. Equivalently E_n = -Ei * Z^2 / n^2 with Ei = h*c*R.

input:

  • n = principal quantum number (integer > 0)

  • Z = atomic number (default: 1 for hydrogen)

  • A = mass number of the isotope (for the mendeleev mass lookup)

  • M_atom = atomic mass in kg (overrides the lookup)

  • reduced_mass = if True (default), use the reduced-mass-corrected R_M; if False, use the infinite-nucleus constant Rinf

  • unit = ‘J’ or ‘eV’ (default)

output:

  • energy of level n, in joules or eV (negative value, bound state)

pyphyschemtools.hydrogen.plot_energy_levels(Z=1, A=None, M_atom=None, reduced_mass=True, n2_max=7, series_names=None, to_scale=True, transition_type='absorption', size=(9, 11), show_level_labels=True, show_transition_labels=True, save_as=None)[source]

Draw an energy-level diagram of a hydrogenic atom/ion of nuclear charge Z: a horizontal line for each level n = 1 .. n2_max (labeled “n = 
” on the right, against a true energy axis in eV on the left), a dashed line for the ionization limit at 0 eV with the continuum of free-electron states shaded above it, and the transitions n2 <-> n1 of each series in series_names, drawn as colored arrows and labeled with Greek letters (alpha, beta, 
) in the series’ color.

By default (to_scale=True) the levels are placed at their true energy (eV) on the left-hand axis: since E_n scales as 1/n^2, n=2..n2_max then crowd together near the ionization limit while n=1 sits far below – itself a good illustration of why the levels bunch up as n increases. With to_scale=False the levels are evenly spaced by rank instead (the usual simplified “schematic” textbook diagram), which keeps the n>=2 levels readable but no longer reflects the true energy axis.

transition_type controls both the arrow direction and, within a series, the left-to-right layout: “absorption” (default) draws arrows pointing up (n1 -> n2), ordered left to right by increasing transition size (alpha first); “emission” draws arrows pointing down (n2 -> n1, the electron falling back to n1), ordered left to right by decreasing transition size, all arriving at the same n1.

input:

  • Z = nuclear charge / atomic number (default: 1 for H)

  • A = mass number of the isotope (for the mass lookup)

  • M_atom = atomic mass in kg (overrides the lookup)

  • reduced_mass = if True (default), use the reduced-mass-corrected R_M; if False, use the infinite-nucleus constant Rinf

  • n2_max = highest principal quantum number shown

  • series_names = {n1: name} mapping of lower levels to draw; defaults to SERIES_NAMES (Lyman to Humphreys, n1 = 1 to 6)

  • to_scale = if True (default), levels are placed at their true energy on the left-hand eV axis; if False, they are evenly spaced by rank instead (schematic)

  • transition_type = “absorption” (default) or “emission”; see above

  • show_level_labels = if True (default), label every level “n = 
 (
 eV)” on the right; if False, only n=1 to 5 are labeled (the others still get their line, just no text). The ionization limit label is kept either way.

  • show_transition_labels = if True (default), label each transition with its Greek letter, alpha to epsilon only (the first five transitions of a series) – there is no standard name for higher members, so none is invented and those stay unlabeled regardless of this setting. If False, no per-transition label is drawn at all (the arrows and series names are unaffected).

  • size = (width, height) in inches for a new figure

  • save_as = file path to save the figure to (e.g. “levels.png” or “levels.svg”), passed to pyphyschemtools.core’s save_fig (format taken from the extension, missing directories created automatically). Not saved if None (default)

pyphyschemtools.hydrogen.plot_line_spectrum(Z=1, A=None, M_atom=None, reduced_mass=True, n2_max=12, series_names=None, show_visible=True, log_scale=True, ax=None)[source]

Draw the line spectrum of a hydrogenic atom/ion of nuclear charge Z: a wavelength axis (nm) with one colored vertical line per transition n2 –> n1, colored by series, and the alpha line of each series labeled with an arrow (e.g. “Ly-alpha”).

input:

  • Z = nuclear charge / atomic number (default: 1 for hydrogen)

  • A = mass number of the isotope (for the mendeleev mass lookup)

  • M_atom = atomic mass in kg (overrides the lookup)

  • reduced_mass = if True (default), use the reduced-mass-corrected R_M; if False, use the infinite-nucleus constant Rinf

  • n2_max = highest principal quantum number n2 included

  • series_names = {n1: name} mapping of lower levels to draw; defaults to SERIES_NAMES (Lyman to Humphreys, n1 = 1 to 6)

  • show_visible = if True (default), shade the visible range (380-780 nm)

  • log_scale = if True (default), use a log wavelength axis (the series span several decades, from ~100 nm to several microns)

  • ax = matplotlib Axes to draw on; a new figure is created if None (default)

output:

  • the matplotlib Axes used

pyphyschemtools.hydrogen.rydberg_Z(Z=1, A=None, M_atom=None)[source]

Rydberg constant (in m^-1) corrected for the finite nuclear mass of the given isotope: R = Rinf * M_nucleus / (me + M_nucleus).

Note: the value depends on the nuclear mass only, not on Z. The Z^2 factor belongs to the level/transition formula, not to the Rydberg constant itself.

input:

  • Z = atomic number (default: 1 for hydrogen); used to look up the element and, together with M_atom, to get the nuclear mass

  • A = mass number of the isotope to use. If None (default), the most abundant isotope of element Z (highest abundance among its isotopes with known abundance) is used

  • M_atom = atomic mass in kg; overrides the mendeleev lookup entirely (A is then ignored)

output:

  • Rydberg constant corrected for the reduced mass, in m^-1

pyphyschemtools.hydrogen.spectral_series(Z=1, A=None, M_atom=None, reduced_mass=True, n2_max=12, series_names=None)[source]

Print the spectral series of a hydrogenic atom/ion of nuclear charge Z: for each n1 in series_names, the series limit (as n2 tends to infinity) and every transition n2 –> n1 for n1 < n2 <= n2_max, 
, with the transition energy (eV), wavelength (nm) and frequency (Hz).

The series names (Lyman, Balmer, 
) were historically defined for the hydrogen atom (Z=1). For Z>1 they are only used “by analogy” (the term structure is the same, just scaled by Z^2; e.g. the “Lyman-like” series of He+ is sometimes called its Lyman series in the literature) – printed here with a “-like” suffix to make that explicit.

input:

  • Z = nuclear charge / atomic number (default: 1 for hydrogen)

  • A = mass number of the isotope (for the mendeleev mass lookup)

  • M_atom = atomic mass in kg (overrides the lookup)

  • reduced_mass = if True (default), use the reduced-mass-corrected R_M; if False, use the infinite-nucleus constant Rinf

  • n2_max = highest principal quantum number n2 to print

  • series_names = {n1: name} mapping of lower levels to print; defaults to SERIES_NAMES (Lyman to Humphreys, n1 = 1 to 6)

output:

  • None (prints to stdout)

pyphyschemtools.kinetics module

class pyphyschemtools.kinetics.KORD(t_exp=None, G_exp=None, headers=('Time / s', 'G'), a0=1.0, alpha=1.0, beta=1.0, k_guess=None, G_0_guess=None, G_inf_guess=None, b_inf_guess=None, t_simul_max=15, verbose=True)[source]

Bases: object

Initialize the kinetic study with experimental data. Reaction: alpha A = beta B

Parameters:
  • t_exp (-) – Time values.

  • G_exp (-) – Measured physical quantity (Absorbance, Conductivity, etc.).

Fixed Parameters:
  • alpha (float): Stoichiometric coefficient for A reactant (smallest positive integer). Default is 1.0.

  • beta (float): Stoichiometric coefficient for B product (smallest positive integer). Default is 1.0.

  • a0 (float): Initial concentration. Note: G_theo is independent of a0 for Order 1. Default is 1.0.

Adjustable Variables (Initial Guesses):
  • k_guess (float, optional): Initial estimate for the rate constant. Default is 0.01.

  • G_0_guess (float, optional): Initial estimate for the initial measured value (G at t=0). if None, it will be initialized as G_exp[0]

  • G_inf_guess (float, optional): Initial estimate for the final measured value (G at infinity). if None, it will be initialized as G_exp[-1]

  • b_inf_guess (float, optional): Initial estimate for the final concentration of B ([B] at infinity). if None, it will be initialized as [A](t=0), i.e. a0

Other Args:
  • t_simul_max (float): the maximum time duration for theoretical simulations. It defines the range of the time vector [0, t_simul_max}] used to simulate and plot kinetic curves with simulate_plot

  • verbose (bool): If True defaulk), enables detailed optimization logs (recommended).

  • headers (tuple of strings): headers of the t_exp and G_exp arrays read in the excel file

G0_theo(t, k, G0, Ginf, binf)[source]

Model for Order 0 kinetics

G1_theo(t, k, G0, Ginf)[source]

Model for Order 1 kinetics

G2_theo(t, k, G0, Ginf, binf)[source]

Model for Order 2 kinetics

concentrations(order, t, binf, k)[source]

Calculate the time-dependent concentrations of reactant A and product B.

This method derives the initial concentration (a0) from the fitted final product concentration (binf) using the stoichiometric ratio alpha/beta. It then computes the concentration profiles based on the integrated rate laws for the specified kinetic order.

Parameters:
  • order (int) – Kinetic order (0, 1, or 2).

  • t (array-like) – Time vector for the calculation.

  • binf (float) – Final concentration of product B at t=infinity.

  • k (float) – Rate constant.

Returns:

(a, b) where ‘a’ is the concentration array of reactant A

and ‘b’ is the concentration array of product B.

Return type:

tuple

Notes

  • Order 0: Linear decay/formation until reactant exhaustion.

  • Order 1: Exponential decay/formation.

  • Order 2: Hyperbolic progression based on the 1/[A] linear relationship.

fit(k_guess, G_0_guess, G_inf_guess, A_0_guess, order=1)[source]

Fits the selected kinetic model (Order 0, 1, or 2) to the experimental data.

This method uses non-linear least squares (scipy.optimize.curve_fit) to simultaneously optimize the rate constant (k), the initial and final physical property values (G0, Ginf), and the final product concentration (binf). Physical constraints are applied via parameter bounds to ensure k and binf remain positive.

It includes automated ‘Smart Guessing’ for k, based on initial rates and computes information criteria (AIC/BIC) for model selection.

Parameters:
  • k_guess (float) – Initial estimate for the rate constant (k).

  • G_0_guess (float) – Initial estimate for the physical property at t=0.

  • G_inf_guess (float) – Initial estimate for the physical property at t=infinity.

  • b_inf_guess (float) – Initial estimate for the final product concentration [B].

  • order (int, optional) – Kinetic order of the reaction (0, 1, or 2). Defaults to 1.

Returns:

A dictionary containing the optimized parameters (‘k’, ‘G0’, ‘Ginf’, ‘binf’)

and statistical metrics (‘RMSE’, ‘R2’, ‘t_half’). Returns None if optimization fails to converge.

Return type:

dict

Notes

  • For Order 1, the timing is independent of binf, and alpha is coupled with k; hence binf is kept fixed during optimization.

  • For Orders 0 and 2, binf and stoichiometry (alpha, beta) explicitly define the reaction’s capacity and end-point timing, ensuring physical consistency between the plateau and the slope.

get_best_order(verbose=True)[source]

Determines and prints the best model based on the lowest RMSE.

halflife(order, binf, k)[source]

Calculate the half-life (t1/2) for the reaction based on the kinetic order.

The half-life represents the time required for the reactant concentration to reach half of its initial value (a0/2).

Parameters:
  • order (int) – Kinetic order (0, 1, or 2).

  • k (float) – The optimized or guessed rate constant.

Returns:

The calculated half-life value.

Return type:

float

Notes

  • Order 0: t1/2 = a0 / (2 * alpha * k) -> Dependent on a0.

  • Order 1: t1/2 = ln(2) / (alpha * k) -> Independent of a0.

  • Order 2: t1/2 = 1 / (alpha * k * a0) -> Inversely proportional to a0.

static load_from_excel(file_path, exp_number, sheet_name=0, show_data=True)[source]

Static method to extract data from an Excel file. Selects the pair of columns (t, G) corresponding to the experiment number. Also loads parameters (a0, alpha, beta)

Format:
  • Row 1: Headers for t and G

  • Row 2: [A]0 value (in the G column)

  • Row 3: alpha value (in the G column)

  • Row 4: beta value (in the G column)

  • Row 5+: [t, G] data points

plot_all_fits(save_img=None)[source]

Plots experimental data and all three kinetic models for visual comparison. If save_img is provided, saves the plot (png, svg, jpg, pdf according to the extension). Vectorial svg is recommended

simulate_plot(save_img=None)[source]

Plots the initial guesses for all three kinetic orders (0, 1, 2), for example to visualize the starting point of a fit.

If save_img is provided, saves the plot (png, svg, jpg, pdf according to the extension). Vectorial svg is recommended

class pyphyschemtools.kinetics.kbasic[source]

Bases: object

Recherche pédagogique de la constante de vitesse k.

Utilisation typique

kb = kbasic()
kb.read("mesures.xlsx")   # 1) lire les données
kb.fit(ordre=1)           # 2) chercher le meilleur k
kb.plot()                 # 3) tracer le résultat

La grandeur mesurĂ©e G dĂ©croĂźt avec le temps depuis sa valeur initiale G0. La forme de G(t) dĂ©pend de l’ordre de la rĂ©action :

  • ordre 0 : dĂ©croissance LINÉAIRE

  • ordre 1 : dĂ©croissance EXPONENTIELLE (le cas le plus courant)

  • ordre 2 : dĂ©croissance HYPERBOLIQUE

fit(ordre=1, G0=None, k_depart=0.1)[source]

Trouve la valeur de k qui minimise le RMSD pour l’ordre choisi.

Si G0 n’est pas donnĂ©, on le prend Ă©gal Ă  la premiĂšre valeur mesurĂ©e. Sinon, on utilise la valeur fournie par l’utilisateur.

Retourne : (k_optimal, rmsd_au_minimum)

plot()[source]

Trace la comparaison données / modÚle et le paysage du RMSD.

read(fichier=None, colab=False)[source]

Lit un fichier Excel à deux colonnes (temps, G) et affiche un récapitulatif sous forme de DataFrame pandas.

DĂ©tecte automatiquement si la premiĂšre ligne est un en-tĂȘte. Si oui, les noms de colonnes serviront de labels pour les axes du tracĂ©.

Retourne le DataFrame des données lues.

Arguments :
fichierchemin (ou URL) du fichier Excel Ă  lire.

Inutile si colab=True (on choisit le fichier à l’upload).

colabsi True, ouvre le bouton d’upload de Google Colab

et lit le fichier choisi. Défaut False.

pyphyschemtools.misc module

class pyphyschemtools.misc.QRCodeGenerator(box_size=40, border=1, version=4)[source]

Bases: object

A utility class to generate QR codes with embedded logos for pyphyschemtools. Initialize the generator with specific QR parameters.

Parameters:
  • box_size (int) – The size of each box in the QR code grid.

  • border (int) – The thickness of the white border.

  • version (int) – The complexity of the QR code (1 to 40).

generate(url, logo_path, fill_color='#1a525f', back_color='white', save_path=None, logo_ratio=4, width=250, flatten=False)[source]

Creates a QR code with a centered logo, saves it to disk, and displays it.

If save_path is not provided, the image is saved in the logo’s directory with a qrcode_ prefix.

Parameters:
  • url (str) – The target URL for the QR code.

  • logo_path (str) – Path to the logo image file.

  • fill_color (str) – Hex code or name for the QR code color.

  • back_color (str) – Background color.

  • save_path (str, optional) – Custom path to save the PNG. Defaults to None.

  • logo_ratio (float) – Ratio of logo size relative to QR code size (default 1/4).

  • width (int) – Display width for Jupyter Notebook rendering.

  • flatten (bool) – If True, removes transparency by placing the logo on a solid white background. Defaults to False.

Returns:

The generated QR code image object.

Return type:

PIL.Image

pyphyschemtools.nano module

pyphyschemtools.nano.get_coordination_numbers(mol: Atoms, cutoff: float = None)[source]

Calculates the coordination number (CN) for each atom in an ASE Atoms object.

This function determines how many neighbors each atom has based on a distance threshold. If no cutoff is provided, it automatically estimates one based on the 1st percentile of the interatomic distance distribution.

Parameters:
  • mol (ase.Atoms) – The structural model (nanoparticle, molecule, or crystal).

  • cutoff (float, optional) – The distance threshold (in Angstroms) to define a chemical bond. Defaults to None (automatic detection).

Returns:

A tuple containing:
  • cn (numpy.ndarray): An array of integers representing the CN of each atom.

  • used_cutoff (float): The actual cutoff value used for the calculation.

Return type:

tuple

pyphyschemtools.nano.view_coordination(mol: Atoms, cutoff: float = None, stick_radius: float = 0.1, sphere_scale: float = 0.6, w=600, h=400, color_map='YlOrRd')[source]

Visualizes a structure using py3Dmol with atoms color-coded by coordination number.

This function computes the coordination environment and generates a 3D ball-and-stick model where colors represent the connectivity (e.g., surface vs. bulk atoms). A Matplotlib legend is displayed alongside the 3D view.

The color logic is optimized for nanoparticles: - CN < 5 : Pastel (low coordination/isolated) - CN 5-13: Sequential Gradient (surface to bulk transition) - CN > 13: Deep Dark (high density/interstitials)

Parameters:
  • mol (ase.Atoms) – The structural model to visualize.

  • cutoff (float, optional) – Distance threshold for bond detection. Defaults to None (auto-detect).

  • stick_radius (float, optional) – The thickness of the bonds in the 3D view. Defaults to 0.1.

  • sphere_scale (float, optional) – The size multiplier for the atomic spheres. Defaults to 0.6.

  • w (float, optional) – Width of the window Defaults to 600

  • h (float, optional) – Height of the window Defaults to 400

  • color_map (str, optional) – The Matplotlib colormap to use for discrete CN values. Defaults to “YlOrRd” (recommended!).

Returns:

The interactive viewer object.

Return type:

py3Dmol.view

pyphyschemtools.orgachem module

class pyphyschemtools.orgachem.FunctionalGroupExplorer[source]

Bases: object

A comprehensive educational tool for organic chemistry within the pyphyschemtools suite.

This class provides an interactive interface for: - Exploring functional groups using SMARTS patterns. - Retrieving IUPAC nomenclature via PubChem API. - Visualizing molecules in 2D (with highlighting) and 3D. - Training via a Quiz system with fuzzy logic validation and survival mechanics.

T(key)[source]
afficher_quiz_nom()[source]
afficher_quiz_struct()[source]
check_nom(b)[source]
check_struct(b)[source]
detecter_delimiteur(fichier)[source]
fuzzy_match(user_input, expected)[source]

Retourne Vrai si la réponse est ressemblante à > 80%

get_lives_html()[source]
get_match_svg(smiles, query)[source]
mol_to_svg(mol, highlightAtoms=None, highlightBonds=None, size=(300, 200))[source]
next_nom(b=None)[source]
next_struct(b=None)[source]
on_lang_change(change)[source]
on_survival_change(change)[source]
run_3d(b)[source]
run_iupac(b)[source]
setup_ui()[source]
show_3d_mol(smiles)[source]
start_timer_thread(progress_bar, callback_timeout)[source]
timeout_struct()[source]
update_combobox_options()[source]

Mise Ă  jour des options de la Combobox et du dictionnaire de correspondance

update_explorer(cat)[source]
update_labels()[source]

pyphyschemtools.spectro module

class pyphyschemtools.spectro.QuantitativeAnalysis(x=None, y=None, x_label='Concentration', y_label='Area')[source]

Bases: object

A comprehensive tool for chemical analysis calibration (e.g., Chromatography, Spectroscopy).

This class handles data ingestion from multiple sources, performs linear regression, provides statistical diagnostics (RÂČ, LOD, LOQ), and generates publication-quality plots including residual analysis and confidence intervals.

x

Independent variable data (usually concentration or amount).

Type:

numpy.ndarray

y

Dependent variable data (usually peak area, absorbance, or signal).

Type:

numpy.ndarray

x_label

Label for the x-axis used in plotting.

Type:

str

y_label

Label for the y-axis used in plotting.

Type:

str

model

Storage for the regression parameters after fitting.

Type:

scipy.stats._stats_mstats_common.LinregressResult or None

fit_linear(intercept=None)[source]

Perform a linear least-squares regression and compute analytical diagnostics.

This method calculates the best-fit line (y = ax + b) for the calibration data. The intercept b is either fitted (ordinary least squares, default) or forced to a given value (e.g. b = 0 for the Beer-Lambert law); in the latter case, only the slope is fitted, with scipy.optimize.curve_fit.

It computes standard statistical metrics (Slope, Intercept, RÂČ) and specific analytical chemistry performance indicators (MAE, RMSE, LOD, LOQ) to evaluate the method’s sensitivity and reliability.

The results are printed to the console in a formatted table and stored within the self.diagnostics dictionary for programmatic access.

Parameters:

intercept (float or None, default None) – None -> slope and intercept are both fitted (scipy.stats.linregress). float -> intercept forced to this value; only the slope is fitted (scipy.optimize.curve_fit).

model

Regression parameters, with attributes slope, intercept, rvalue, stderr (slope standard error) and intercept_stderr (0 if forced). Used by plot_calibration() and predict().

Type:

types.SimpleNamespace

diagnostics

A dictionary containing key analytical performance indicators:

  • ‘slope_err’: Standard error of the slope.

  • ‘intercept_err’: Standard error of the intercept (0 if forced).

  • ‘r_squared’: Coefficient of determination.

  • ‘mae’: Mean Absolute Error.

  • ‘rmse’: Root Mean Square Error.

  • ‘lod’: Limit of Detection.

  • ‘loq’: Limit of Quantification.

  • ‘sy_x’: Residual standard deviation.

  • ‘forced_intercept’: True if the intercept was forced.

Type:

dict

Notes

  • RÂČ is computed as 1 - SS_res/SS_tot, with SS_tot calculated around the mean of y, in both cases, so that free and forced fits can be compared.

  • MAE (Mean Absolute Error) and RMSE (Root Mean Square Error): average error on the signal, in the same units as y.

  • sy_x: Residual standard deviation, with n - 2 degrees of freedom (free intercept) or n - 1 (forced intercept).

  • LOD (Limit of Detection): 3 sy_x / slope.

  • LOQ (Limit of Quantification): 10 sy_x / slope.

Example

>>> calib = QuantitativeAnalysis(conc, absorbance)
>>> calib.fit_linear()             # free intercept
>>> calib.fit_linear(intercept=0)  # line forced through the origin
>>> print(calib.diagnostics['lod'])
classmethod from_excel(file_path, x_col=1, y_col=2, sheet_name=0)[source]

Classmethod to create a QuantitativeAnalysis instance from an Excel or ODS file.

Parameters:
  • file_path (str or Path) – Path to the .xlsx or .ods file.

  • x_col (int or str, optional) – Column number (starting at 1) or Name (str) for X. Default is 1.

  • y_col (int or str, optional) – Column number (starting at 1) or Name (str) for Y. Default is 2.

  • sheet_name (str or int, optional) – The specific sheet to read from. Default is 0 (the first sheet).

plot_calibration(save_img=None, figsize=(20, 20), scientific=True, marker='o', color_marker='#780000', color_fit='#0b78b3', linestyle='-', fontsize=12)[source]

Generates a diagnostic plot featuring the calibration curve and residual analysis.

The figure consists of two subplots:

  1. Top Panel: Regression Line & Uncertainty Displays the experimental data points (x, y), the calculated OLS regression line, and a 95% Prediction Interval. The interval is calculated as 1.96 * sigma, where sigma (sy_x) is the Standard Deviation of the Residuals.

  2. Bottom Panel: Residual Analysis Plots the residuals (y_exp - y_calc) against concentration. This panel is essential for checking homoscedasticity. A random distribution around the zero-line validates the linear model, whereas a structured pattern (e.g., U-shape) indicates non-linearity.

Parameters:
  • save_img (str, optional) – Path or filename to save the figure (e.g., ‘plot.png’, ‘report.svg’). If the file exists, a manual confirmation will be requested. Vectorial formats (.svg, .pdf) are recommended for publications.

  • figsize (tuple, default (20, 20)) – Width and height of the figure, in cm.

  • scientific (bool, default True) – If True, forces scientific notation (e.g., 1e+05) on the Y-axis.

  • marker (str, default "o") – Style of the experimental data points.

  • color_marker (str, default "#780000") – Color of the experimental scatter points.

  • color_fit (str, default "#0b78b3") – Color of the regression line and the prediction interval.

  • linestyle (str, default "-") – Line style for the linear fit.

  • fontsize (int, default 12) – Base font size for all text elements in the figure. The titles are set to fontsize + 2, while the axis labels use fontsize. The legend and tick labels are automatically scaled to fontsize - 2 and fontsize - 1 respectively.

Raises:

ValueError – If the method is called before fitting the model with fit_linear().

Notes

The 95% Prediction Interval represents the range within which a new single observation is expected to fall. It is wider than a Confidence Interval as it accounts for both the model uncertainty and the inherent variance (sigma) of the residuals.

predict(signals, sample_name='Sample')[source]

Prediction of concentration statistics from analytical signals.

Calculates the mean and standard deviation of the provided signals, applies the inverse linear model, prints a formatted analysis report, and store values in attributes.

Parameters:
  • signals (float or list/numpy.ndarray) – The analytical signal(s) measured (e.g., Absorbance, Area).

  • sample_name (str, optional) – A name for the sample for the report (default is “Sample”).

Notes

This method updates the following instance attributes:

  • mean_conc: The calculated mean concentration.

  • std_conc: The estimated uncertainty of the concentration.

  • mean_signal: The average value of the input signals.

class pyphyschemtools.spectro.SpectrumSimulator(sigma_ev=0.3, plotWH=(12, 8), fontSize_axisText=14, fontSize_axisLabels=14, fontSize_legends=12, fontsize_peaks=12, colorS='#3e89be', colorVT='#469cd6')[source]

Bases: object

Initializes the spectrum simulator

Parameters:
  • sigma_ev (-) – Gaussian half-width at half-maximum in electron-volts (eV). Default is 0.3 eV (GaussView default is 0.4 eV).

  • plotWH (-) – Width and Height of the matplotlib figures in inches. Default is (12,8).

  • colorS (-) – color of the simulated spectrum (default =’#3e89be’)

  • colorVT (-) – color of the vertical transition line (default = ‘#469cd6’)

Returns:

This method initializes the instance attributes.

Return type:

None

Calculates:

sigmanm = half-width of the Gaussian band, in nm

plotAbs_lambda_TDDFT(datFiles=None, C0=1e-05, lambdamin=200, lambdamax=800, Amax=2.0, titles=None, linestyles=[], annotateP=[], tP=0.1, resetColors=False, save_img=None)[source]

Plots a simulated TDDFT VUV absorbance spectrum (transitions summed with gaussian functions) between lambdamin and lambdamax (sum of states done in the range [lambdamin-50, lambdamlax+50] nm)

Parameters:
  • datFiles – list of pathway/name to files generated by ‘GParser Gaussian.log -S’

  • C0 – list of concentrations needed to calculate A = epsilon x l x c (in mol.L-1)

  • lambdamin – plot range (x axis)

  • lambdamax – plot range (x axis)

  • Amax – y axis graph limit

  • titles – list of titles (1 per spectrum plot)

  • linestyles – list of line styles(default = “-”, i.e. a continuous line)

  • annotateP – list of Boolean (annotate lambda max True or False. Default = True)

  • tP – threshold for finding the peaks (default = 0.1)

  • resetColors (bool) – If True, resets the matplotlib color cycle to the first color. This allows different series (e.g., gas phase vs. solvent) to share the same color coding for each molecule across multiple calls. Default: False

  • save – saves in a png file (300 dpi) if True (default = False)

  • save_img – saves figure in a 300 dpi png file if not None (default), with save_img=full pathway

plotAbs_lambda_exp(csvFiles, C0, lambdamin=200, lambdamax=800, Amax=2.0, titles=None, linestyles=[], annotateP=[], tP=0.1, save_img=None)[source]

Plots an experimental VUV absorbance spectrum read from a csv file between lambdamin and lambdamax

Parameters:
  • superpose (-) – False = plots a new graph, otherwise the plot is superposed to a previously created one (probably with plotAbs_lambda_TDDFT())

  • csvfiles (-) – list of pathway/name to experimental csvFiles (see examples for the format)

  • C0 (-) – list of experimental concentrations, i.e. for each sample

  • lambdamin (-) – plot range (x axis)

  • lambdamax – plot range (x axis)

  • Amax (-) – graph limit (y axis)

  • titles (-) – list of titles (1 per spectrum plot)

  • linestyles (-) – list of line styles(default = “–”, i.e. a dashed line)

  • annotateP (-) – list of Boolean (annotate lambda max True or False. Default = True)

  • tP (-) – threshold for finding the peaks (default = 0.1)

  • save (-) – saves in a png file (300 dpi) if True (default = False)

  • save_img (-) – saves figure in a 300 dpi png file if not None (default), with save_img=full pathway

plotEps_lambda_TDDFT(datFile, lambdamin=200, lambdamax=800, epsMax=None, titles=None, tP=10, ylog=False, save_img=None)[source]

Plots a TDDFT VUV simulated spectrum (vertical transitions and transitions summed with gaussian functions) between lambdamin and lambdamax

The sum of states is done in the range [lambdamin-50, lambdamax+50] nm.

Parameters:
  • datFile – list of pathway/names to “XXX_ExcStab.dat” files generated by ‘GParser Gaussian.log -S’

  • lambdamin – plot range

  • lambdamax – plot range

  • epsMax – y axis graph limit

  • titles – list of titles (1 per spectrum plot)

  • tP – threshold for finding the peaks (default = 10 L. mol-1 cm-1)

  • ylog – y logarithmic axis (default: False).

  • save – saves in a png file (300 dpi) if True (default = False)

  • save_img – saves figure in a 300 dpi png file if not None (default), with save_img=full pathway

plotTDDFTSpectrum(wavel, sumInt, wavelTAB, feTAB, tP, ylog, labelSpectrum, colorS='#0000ff', colorT='#0000cf')[source]

Called by plotEps_lambda_TDDFT. Plots a single simulated UV-Vis spectrum, i.e. after gaussian broadening, together with the TDDFT vertical transitions (i.e. plotted as lines)

Parameters:
  • wavel – array of gaussian-broadened wavelengths, in nm

  • sumInt – corresponding molar absorptiopn coefficients, in L. mol-1 cm-1

  • wavelTAB – wavelength of TDDFT, e.g. discretized, transitions

  • ylog – log plot of epsilon

  • tP – threshold for finding the peaks

  • feTAB – TDDFT oscillator strength for each transition of wavelTAB

  • labelSpectrum – title for the spectrum

pyphyschemtools.symmetry module

Molecular symmetry for teaching purposes.

Symmetry operations are written as 3x3 matrices and applied to the atomic coordinates of a molecule. Tracking where each atom goes after an operation gives the characters of the atomic representation Γ_atoms, which can then be reduced with the character table of the point group.

pyphyschemtools.symmetry.Cn(n, axis='z', k=1)[source]

Proper rotation C_n^k about an axis passing through the origin.

Parameters:
  • n (int) – order of the axis (rotation angle 360°/n).

  • axis (str or array-like) – “x”, “y”, “z” (default) or a direction, e.g. (1, 1, 1).

  • k (int) – power of the operation (rotation angle k*360°/n).

Returns:

3x3 rotation matrix.

Return type:

np.ndarray

class pyphyschemtools.symmetry.MolSym(symbols, coords, group=None, tol=0.05, lang='En', standard_orientation=True, sym_tolerance=0.3, verbose=True)[source]

Bases: object

Symmetry analysis of a molecule: atom tracking under the symmetry operations of its point group, atomic representation Γ_atoms and its reduction into irreducible representations.

By default (standard_orientation=True), the molecule is placed in the standard orientation of its point group, as the “Standard orientation” of Gaussian: principal axis along z; for C2v, molecular plane = yz; for Dnh, one C2’ axis along x, through the largest number of atoms. If the molecule is not already in a standard frame, its symmetry operations are given by pymatgen. The coordinates are translated to the center of mass and symmetrized; the initial ones are kept in coords_input.

Parameters:
  • symbols (list of str) – chemical symbols of the atoms.

  • coords (array-like) – Cartesian coordinates, shape (n_atoms, 3), in Å.

  • group (str) – Schoenflies symbol of the point group (see available_groups()); if None, detected with pymatgen.

  • tol (float) – tolerance (Å) used to decide that two atoms coincide.

  • lang (str) – language of the messages and tables (“En” (default) or “Fr”).

  • standard_orientation (bool) – if True (default), places the molecule in the standard orientation of its point group.

  • sym_tolerance (float) – tolerance (Å) of the symmetry detection (pymatgen) and of the symmetrization.

  • verbose (bool) – if True (default), prints the point group and the orientation of the molecule at its creation.

group

Schoenflies symbol of the point group, e.g. “C2v”.

Type:

str

symbols

chemical symbols of the atoms.

Type:

list

atom_labels

labels of the atoms, e.g. [“O0”, “H1”, “H2”].

Type:

list

coords

coordinates (Å) used by the module (standard orientation).

Type:

np.ndarray

coords_input

initial coordinates, centred on the center of mass.

Type:

np.ndarray

labels

labels of the classes of operations (columns of the character table).

Type:

list

order

order h of the group (number of operations).

Type:

int

activity(chi, show=True)[source]

IR and Raman activity of the irreducible representations contained in a representation: IR active if the irrep transforms as x, y or z, Raman active if it transforms as a quadratic function (xÂČ, xy
).

Parameters:
  • chi (array-like) – characters of the representation, one per class.

  • show (bool) – if True, prints the active irreps. With show=True, nothing is returned (no echo in a notebook); use show=False to get the result.

Returns:

{“IR”: [
], “Raman”: [
]}, irreps with their multiplicities.

Return type:

dict

apply(op)[source]

Coordinates of the atoms after a symmetry operation.

Parameters:

op (str or np.ndarray) – class label (e.g. “C2”, “σv”) or 3x3 matrix.

Returns:

transformed coordinates, shape (n_atoms, 3).

Return type:

np.ndarray

bonds(scale=1.25)[source]

Bonds detected from the distances: d(A-B) < scale x (r_cov(A) + r_cov(B)), with the covalent radii of RDKit.

Returns:

list of tuples (i, j), i < j.

character_table(gamma=True, functions=True, complex=False)[source]

Character table of the point group, as a pandas DataFrame.

Parameters:
  • gamma (bool) – if True, adds the row Γ_atoms at the bottom of the table.

  • functions (bool) – if True, adds the columns of the basis functions.

  • complex (bool) – if True, complex form of the pairs of complex conjugate irreps.

equivalent_atoms()[source]

Sets of symmetry-equivalent atoms (orbits of the group).

Returns:

list of lists of atom indices.

fixed_atoms(op)[source]

Labels of the atoms that stay in place under the operation.

flowchart()[source]

Flowchart (decision tree) of the point groups, with the path leading to the group of the molecule.

classmethod from_molView(mv, group=None, display_now=False, **kwargs)[source]

Builds the molecule from a molView object (Chem3D module). MolSym does not read structures itself: molView reads a SMILES (3D structure from PubChem or generated by RDKit), a file (xyz, pdb, mol
), a PubChem CID


MolSym.from_molView(molView(“O”, source=”smiles”, display_now=False)) MolSym.from_molView(molView(“SF6_model.xyz”, source=”file”, display_now=False)) MolSym.from_molView(molView(962, source=”cid”, display_now=False))

The point group is detected with pymatgen (unless given), then the molecule is placed in the standard orientation of its point group and symmetrized (3D structures from PubChem or RDKit are not exactly symmetric).

Parameters:
  • mv (molView) – molecule loaded with molView.

  • group (str) – Schoenflies symbol; if None, detected with pymatgen.

  • display_now (bool) – if True, displays the molecule in 3D, in its standard orientation (see show). False by default, since molView already displays the molecule (its own display_now argument).

  • **kwargs – passed to MolSym (tol, lang, standard_orientation, sym_tolerance, verbose).

gamma_3N(show=True)[source]

Representation spanned by the 3N cartesian displacements of the atoms: χ_3N(R) = (number of atoms that stay in place) x χ_xyz(R), where χ_xyz(R) = trace of the matrix of R.

Parameters:

show (bool) – if True, displays Γ_atoms, Γ_xyz and Γ_3N with their reductions. With show=True, nothing is returned (no echo in a notebook); use show=False to get the characters.

Returns:

characters of Γ_3N, one per class (show=False).

Return type:

np.ndarray

gamma_atoms(show=True)[source]

Characters of the atomic representation Γ_atoms: for each class, the number of atoms that stay in place under the operation.

Parameters:

show (bool) – if True, displays the table with the fixed atoms. With show=True, nothing is returned (no echo in a notebook); use show=False to get the result.

Returns:

characters of Γ_atoms, one per class.

Return type:

np.ndarray

gamma_bonds(bonds=None, show=True)[source]

Representation spanned by bond stretchings (internal coordinates): for an operation R, a bond that is sent onto itself (possibly with its two ends exchanged) contributes 1, a bond that moves contributes 0. The reduction, given for each set of equivalent bonds, gives the symmetries of the stretching vibrational modes (e.g. the number of IR / Raman active Μ(CO) bands of a metal carbonyl).

Parameters:
  • bonds (list) – bonds to consider, as pairs of atom indices [(0, 1), 
], or as element pairs [“C-H”, “C-O”]; if None, all the bonds detected from the distances (see bonds()).

  • show (bool) – if True, displays the table of the characters and of the reductions. With show=True, nothing is returned (no echo in a notebook); use show=False to get the result.

Returns:

characters of the total representation, one per class.

Return type:

np.ndarray

gamma_orbitals(basis='valence', show=True)[source]

Representation spanned by a basis of atomic orbitals, and its reduction for each set of equivalent atoms and each shell (s, p, d, f): the symmetries of the symmetry-adapted linear combinations (SALCs), i.e. the building blocks of a molecular orbital diagram.

For an operation R, an atom that stays in place contributes χ_l(R): 1 for s, the trace of R for p (p orbitals transform as x, y, z), etc.; an atom that moves contributes 0.

Parameters:
  • basis (str or dict) – “valence” (default): s for H and He, s and p for the main group elements, s, p, d for the d block, s, p, d, f for the f block; or the same shells on all the atoms, e.g. “s”, “pz”, “sp”, [“s”, “px”, “py”]; or a dict giving the shells of each element, e.g. {“C”: “sp”, “H”: “s”} or {“Fe”: “spd”, “C”: “p”, “H”: “”}. “px”, “py” or “pz” alone: the p orbitals perpendicular to the molecular plane, i.e. a π basis, e.g. {“C”: “pz”} for benzene (molecular plane xy in the standard orientation of D6h), {“C”: “px”} for a planar C2v molecule (molecular plane yz); “pxy”, “pxz”, “pyz”: the p orbitals lying in the molecular plane (σ basis), e.g. {“C”: “s pxy”, “H”: “s”} for benzene.

  • show (bool) – if True, displays the table of the characters and of the reductions. With show=True, nothing is returned (no echo in a notebook); use show=False to get the result.

Returns:

characters of the total representation, one per class.

Return type:

np.ndarray

gamma_vib(show=True)[source]

Representation of the 3N-6 vibrational modes (non-linear molecule): Γ_vib = Γ_3N - Γ_trans - Γ_rot, with χ_trans(R) = trace(R) (x, y, z) and χ_rot(R) = det(R) x trace(R) (Rx, Ry, Rz: axial vectors), followed by the IR / Raman activity of the modes.

Parameters:

show (bool) – if True, displays Γ_3N, Γ_trans, Γ_rot and Γ_vib with their reductions, and the IR / Raman activity. With show=True, nothing is returned (no echo in a notebook); use show=False to get the characters.

Returns:

characters of Γ_vib, one per class (show=False).

Return type:

np.ndarray

is_symmetry(op)[source]

True if the operation leaves the molecule unchanged.

matrices(op=None, all_operations=False, exact=True)[source]

Displays the matrices of the symmetry operations of the group (LaTeX).

Parameters:
  • op (str or list of str) – class label(s) (e.g. “C3”, [“C2”, “σv”]); if None, all the classes.

  • all_operations (bool) – if False (default), one representative per class; if True, all the operations of the class(es), named by identify.

  • exact (bool) – if True, exact forms of the entries (1/2, √3/2
) when possible.

orbital_symmetries(coeffs, energies, atoms=None, shell='pz', tol=0.0001, show=True)[source]

Irreducible representations of all the MOs of a set, degenerate MOs being grouped. The MOs are expanded on ONE atomic orbital per atom, all of the same type (s, px, py or pz), e.g. the π MOs of a HĂŒckel calculation; see orbital_symmetry().

Parameters:
  • coeffs (array-like) – coefficients, 2D array of shape (n, number of MOs): one row per atom of atoms (same order), one column per MO (e.g. HMO.c_MOs).

  • energies (array-like) – energies of the MOs, one per column of coeffs (or HĂŒckel x values, e.g. HMO.E_MOs), used to group the degenerate MOs; they do not need to be sorted.

  • atoms (list) – indices (in the molecule) of the n atoms carrying the basis orbitals, in the order of the rows of coeffs (default: all the atoms).

  • shell (str) – “s”, “px”, “py” or “pz”.

  • tol (float) – two MOs are degenerate if their energies differ by less than tol; also used to check the symmetry of the MOs.

  • show (bool) – if True, displays the table. With show=True, nothing is returned; use show=False to get the DataFrame.

Returns:

MOs (column indices), energy, irrep (show=False).

Return type:

pandas.DataFrame

orbital_symmetry(C, atoms=None, shell='pz', tol=0.0001, show=True)[source]

Irreducible representation of a molecular orbital (or of a set of degenerate MOs) expanded on ONE atomic orbital per atom, all of the same type (s, px, py or pz): e.g. a HĂŒckel π MO on the pz orbitals, or an MO built from the 1s orbitals of hydrogen atoms. The MOs may come from any calculation (HĂŒckel, or the corresponding coefficients of an ab initio / DFT calculation), as long as the basis is one orbital per atom: MOs mixing several orbitals on the same atom (s, p and d
) are not handled.

Parameters:
  • C (array-like) – coefficients of the MO, 1D array of length n (one coefficient per atom of atoms, in the same order), or of a set of degenerate MOs, 2D array of shape (n, number of MOs), one column per MO.

  • atoms (list) – indices (in the molecule) of the n atoms carrying the basis orbitals, in the order of the coefficients (default: all the atoms). All the atoms equivalent by symmetry must be included.

  • shell (str) – “s”, “px”, “py” or “pz”: orbital on each atom (for a π system, the p orbital perpendicular to the molecular plane, see orientation()).

  • tol (float) – tolerance used to check that the MOs span a representation (numerical coefficients of a quantum chemistry code are not exact).

  • show (bool) – if True, prints the characters and the irrep. With show=True, nothing is returned (no echo in a notebook); use show=False to get the result.

Returns:

the irreducible representation(s), e.g. “E1g” (show=False).

Return type:

str

orientation(show=True)[source]

Describes the orientation of the molecule in the cartesian frame: shape (linear, planar or not), molecular plane (xy, xz, yz or other) or axis, and principal axis of the point group.

Parameters:

show (bool) – if True, prints the description and returns nothing; if False, returns the dict without printing.

Returns:

{“shape”: 
, “plane”: 
, “axis”: 
, “principal_axis”: 
}

Return type:

dict

reduce(chi=None, show=True)[source]

Reduction of a representation into irreducible representations: n_i = (1/h) ÎŁ_classes g_c χ(c) χ_i(c). A pair of complex conjugate irreps (row marked * in the character table) is counted as a whole.

Parameters:
  • chi (array-like) – characters of the representation, one per class (default: Γ_atoms of the molecule).

  • show (bool) – if True, prints the decomposition (e.g. Γ = 2A1 + B2). With show=True, nothing is returned (no echo in a notebook); use show=False to get the result.

Returns:

number of times each irreducible representation appears.

Return type:

dict

representation_matrix(op, basis='s', atoms=None, show=True)[source]

Matrix of a symmetry operation in a basis of atomic orbitals. For a basis of s orbitals, it is the permutation matrix of the atoms; for p orbitals, each block is the 3x3 matrix of the operation itself. The trace of the matrix is the character of the operation.

Parameters:
  • op (str or np.ndarray) – class label (e.g. “C2”) or 3x3 matrix.

  • basis (str, list or dict) – orbitals on each atom, as in gamma_orbitals: “s” (default), “p”, “sp”, “d”, “f”, “valence”, “pz”, [“s”, “px”], or a dict per element, e.g. {“O”: “sp”, “H”: “s”}.

  • atoms (list) – atoms carrying the basis orbitals (default: all the atoms).

  • show (bool) – if True, displays the matrix (LaTeX), the basis and the trace; if False, returns the matrix without display.

Returns:

the matrix (show=False).

Return type:

np.ndarray

show(labels=False, axes=False, width=500, height=400)[source]

Interactive 3D view (py3Dmol) of the molecule alone, in its standard orientation.

Parameters:
  • labels (bool) – if True, shows the atom labels (O0, H1
).

  • axes (bool) – if True, shows the cartesian axes x, y, z.

  • width (int) – size of the viewer in pixels.

  • height (int) – size of the viewer in pixels.

show_elements(op=None, labels=False, axes=True, width=500, height=400)[source]

Interactive 3D view (py3Dmol) of the molecule and of its symmetry elements.

Parameters:
  • op (str or list of str) – class label(s) (e.g. “C3”, [“S4”, “C2”]): shows only the elements of these classes. If None, shows all the proper axes, planes and the inversion center (can be crowded for high symmetry groups).

  • labels (bool) – if True, shows the atom labels (O0, H1
).

  • width (int) – size of the viewer in pixels.

  • height (int) – size of the viewer in pixels.

Colors: C2 red, C3 green, C4 blue, C5 orange, C6 purple, C8 brown; Sn axes dashed; planes in translucent blue; inversion center in black.

show_operation(op, highlight=None, axes=True, width=700, height=350)[source]

Interactive 3D view (py3Dmol) of the molecule before (left) and after (right) a symmetry operation. Each atom keeps its label, so that the atom tracking can be read on the figure. The two views are linked.

Parameters:
  • op (str) – class label (e.g. “C3”, “σv”); the representative of the class is used.

  • highlight (int or list of int) – atom(s) to follow: a translucent yellow sphere marks the atom before the operation (left) and the place where it arrives after the operation (right).

  • axes (bool) – if True, shows the cartesian axes x, y, z.

  • width (int) – size of the viewer in pixels.

  • height (int) – size of the viewer in pixels.

symmetry_elements(op=None)[source]

Symmetry elements of the molecule (axes, planes, inversion center).

Parameters:

op (str or list of str) – class label(s) (e.g. “C3”, [“S4”, “C2”]): elements of these classes only. If None, all the elements: proper axes (labelled by their highest order), planes and inversion center.

Returns:

list of tuples (type, vector, label), type being ‘axis’, ‘improper’, ‘plane’ or ‘center’.

track(op, verbose=True)[source]

Atom tracking: for each atom, the index of the atom on which it lands after the symmetry operation.

Parameters:
  • op (str or np.ndarray) – class label (e.g. “C2”, “σv”) or 3x3 matrix.

  • verbose (bool) – if True, prints the tracking (e.g. H1 → H2).

Returns:

destination index of each atom, or None for an atom that lands

on no atom of the same element (the operation is then not a symmetry operation of the molecule).

Return type:

list

pyphyschemtools.symmetry.Sn(n, axis='z', k=1)[source]

Improper rotation S_n^k: rotation C_n^k followed by a reflection through the plane perpendicular to the axis.

Parameters:
  • n (int) – order of the axis.

  • axis (str or array-like) – “x”, “y”, “z” (default) or a direction, e.g. (1, 1, 1).

  • k (int) – power of the operation.

pyphyschemtools.symmetry.available_groups()[source]

List of the point groups whose character table is available.

pyphyschemtools.symmetry.character_table(group, functions=True, lang='En', complex=False)[source]

Character table of a point group, as a pandas DataFrame.

Pairs of complex conjugate irreducible representations (groups C3
C8, S4, S6, S8, C3h
C8h, T, Th) are given by default as a single real row (sum of the two characters), marked with *. With complex=True, the two components are given separately (ÂčE, ÂČE), with Δ = exp(2πi/n).

Parameters:
  • group (str) – Schoenflies symbol of the point group (see available_groups()).

  • functions (bool) – if True, adds the columns of the basis functions (linear functions and rotations, quadratic functions).

  • lang (str) – language of the messages (“En” (default) or “Fr”).

  • complex (bool) – if True, complex form of the pairs of complex conjugate irreps.

pyphyschemtools.symmetry.identify(M, tol=1e-06, with_inverse=False)[source]

Name of a symmetry operation given as a 3x3 matrix: E, i, σ(xy), C3(z), C3ÂČ(z), S4Âł(z), C3(1,1,1)


Vertical planes and axes lying in the xy plane are located by the angle φ of their direction in the xy plane, measured from x: σ(z,60°) is the plane containing z and the direction at 60° from x (σ(z,0°) = σ(xz), σ(z,90°) = σ(yz)); C2(xy,30°) is the C2 axis in the xy plane at 30° from x. Other planes are given by their normal: σ⊄(1,1,1).

The direction of an axis is oriented so that its first non-zero component is positive, and the rotation angle follows the right-hand rule.

Parameters:
  • M (np.ndarray) – 3x3 matrix.

  • with_inverse (bool) – if True, also gives the inverse notation when the operation is the inverse of the generator: ‘C3ÂČ(z) = C3⁻Âč(z)’.

Examples

>>> identify(Cn(3) @ Cn(3))
'C3ÂČ(z)'
>>> identify(sigma((0, 0, 1)) @ Cn(2))
'i'
pyphyschemtools.symmetry.identity()[source]

Identity E.

pyphyschemtools.symmetry.inv(M)[source]

Inverse of a symmetry operation. The matrix is orthogonal, so its inverse is its transpose: inv(Cn(3)) = C3⁻Âč = C3ÂČ.

pyphyschemtools.symmetry.inversion()[source]

Inversion i through the origin.

pyphyschemtools.symmetry.ir_raman_activity(group, chi, show=True, lang='En')[source]

IR and Raman activity of the irreducible representations contained in a representation of a point group, without any molecule: IR active if the irrep transforms as x, y or z, Raman active if it transforms as a quadratic function (xÂČ, xy
).

Parameters:
  • group (str) – Schoenflies symbol of the point group.

  • chi (array-like) – characters of the representation, one per class.

  • show (bool) – if True, prints the active irreps and returns nothing; if False, returns the result without printing.

  • lang (str) – language of the messages (“En” (default) or “Fr”).

Returns:

{“IR”: [
], “Raman”: [
]}, irreps with their multiplicities (show=False).

Return type:

dict

pyphyschemtools.symmetry.point_group_flowchart(group=None, lang='En', ax=None)[source]

Flowchart (decision tree) to find the point group of a molecule. If a group is given, the path leading to it is highlighted.

Parameters:
  • group (str) – Schoenflies symbol of the point group to highlight (optional).

  • lang (str) – “En” (default) or “Fr”.

  • ax (matplotlib.axes.Axes) – axes to draw in (optional).

Returns:

matplotlib.figure.Figure

pyphyschemtools.symmetry.reduce_representation(group, chi, show=True, lang='En')[source]

Reduction of a representation of a point group into irreducible representations, without any molecule: n_i = (1/h) ÎŁ_classes g_c χ(c) χ_i(c)*. A pair of complex conjugate irreps (row marked * in the character table) is counted as a whole.

Parameters:
  • group (str) – Schoenflies symbol of the point group.

  • chi (array-like) – characters of the representation, one per class, in the order of the columns of character_table(group).

  • show (bool) – if True, prints the decomposition (e.g. Γ = 2A1 + B2) and returns nothing; if False, returns the result without printing.

  • lang (str) – language of the messages (“En” (default) or “Fr”).

Returns:

number of times each irreducible representation appears (show=False).

Return type:

dict

Example

>>> reduce_representation("C3v", [4, 1, 2])
Γ = 2A1 + E
pyphyschemtools.symmetry.show_matrix(M, name=None, exact=True)[source]

Displays a 3x3 symmetry operation as a LaTeX matrix, with its name.

Parameters:
  • M (np.ndarray) – 3x3 matrix.

  • name (str) – name of the operation; if None, given by identify(M).

  • exact (bool) – if True, exact forms of the entries (1/2, √3/2
) when possible.

pyphyschemtools.symmetry.sigma(plane='xy')[source]

Reflection σ through a plane containing the origin.

Parameters:

plane (str or array-like) – “xy”, “xz” or “yz”, or, for any other plane, the vector normal to the plane, e.g. (1, -1, 0) for the diagonal plane containing z and the bisector of x and y (σd of CH4, D4h
).

Returns:

3x3 reflection matrix.

Return type:

np.ndarray

Examples

>>> sigma("xy")          # σh when the principal axis is z
>>> sigma((1, -1, 0))    # σd containing z and the direction (1, 1, 0)

pyphyschemtools.survey module

class pyphyschemtools.survey.SurveyApp(mode='participant', base_dir='ML-survey')[source]

Bases: object

analyze_text_columns(df=None, columns=None, top_n=20)[source]

Basic textual analysis: show frequent words, word clouds, and per-question summary.

build_admin_dashboard()[source]
build_participant_form()[source]
enable_slider_css()[source]

Inject CSS for hover/active color effects on sliders.

get_or_create_user_id()[source]

Return a persistent anonymous ID (stored in .survey_id).

list_drafts()[source]
load_all_responses()[source]

Load and merge all .csv survey responses into a DataFrame.

load_draft(b)[source]
load_questions()[source]
plot_spider_multi(df, title='Participant and Mean Scores per Block', savepath=None, figsize=(12, 8))[source]

Draw radar (spider) chart with per-participant transparency and block names instead of A–F.

print_questions_summary()[source]

Affiche la liste des questions par bloc et leur type (Numérique/Texte).

run()[source]
save_draft(b)[source]
semantic_analysis(df=None, columns=None, n_clusters=3)[source]

Perform semantic clustering on open-ended responses using sentence-transformers.

submit_form(b)[source]
summarize_by_block(df)[source]

Compute average score per block (A–F) for numeric questions.

pyphyschemtools.sympyUtilities module

pyphyschemtools.sympyUtilities.PrintLatexStyleSymPyEquation(spe)[source]

Function that displays a SymPy expression (spe) in a jupyter notebbok after its conversion into a LaTeX / Math output

Input: spe= SymPy expression

Output: Pretty printing of spe

pyphyschemtools.sympyUtilities.e2Lists(eigenvectors, sort=False)[source]

returns two separate lists from the list of tuples returned by the eigenvects() function of SymPy

input:

  • the list of tuples returned by eigenvects

  • sort (default: False): returns sorted eigenvalues and corresponding eigenvectors if True

output - list of eigenvalues, sorted or not - list of corresponding eigenvectors

pyphyschemtools.tools4AS module

pyphyschemtools.tools4AS.ApplySecondeChance(df, nomCC, nomCCSC, nomCCdelaSC)[source]

modification du dataframe df

entrée :
  • df = dataframe auquel on va ajouter une nouvelle colonne nomCCSC qui va contenir la note de la colonne nomCC soit celle de la colonne nomCCdelaSC, si cell-ci est supĂ©rieure Ă  la notede nomCC

  • nomCC = nom de la colonne Ă  laquelle on applique la seconde chance

  • nomCCSC = nom de la nouvelle colonne qui contient la note du CC aprĂšs application de la seconde chance

  • nomCCdelaSC = nom de la colonne qui contient la note “seconde chance

sortie :
  • moyenne aprĂšs application de la seconde chance

  • Ă©cart-type aprĂšs application de la seconde chance

pyphyschemtools.tools4AS.BoiteAMoustachesByMentionEtParcours(df, Moyenne, Mention, Parcours, NomGraphique)[source]
pyphyschemtools.tools4AS.BoiteAMoustachesByMentionEtParcoursHue(df, Moyenne, Mention, Parcours, NomGraphique)[source]
pyphyschemtools.tools4AS.ComparaisonMoyennesDMCC(df, nomCC1, nomCC2, SeuilBadDMCC1, SeuilGoodDMCC1)[source]
entrée :
  • df = dataframe avec uniquement les Ă©tudiants AJ ou ADM, c’est-Ă -dire qu’il n’y a aucun fantĂŽme

  • nomCC1 = en-tĂȘte de la colonne de df qui contient la note du premier CC

  • nomCC2 = en-tĂȘte de la colonne de df qui contient la note du 2nd CC

  • SeuilBadDMCC1 = Seuil en-dessous duquel la note au nomCC1 est considĂ©rĂ©e comme mĂ©diocre

  • SeuilGoodDMCC1 = Seuil au-deçà duquel la note au nomCC1 est considĂ©rĂ©e comme bonne

affichage :
  • moyenne au nomCC2 de la cohorte d’étudiant(e)s
    • en-dessous du SeuilBadDMCC1 au nomCC1

    • au-dessus du SeuilGoodDMCC1 au nomCC1

    • entre les deux seuils au nomCC1

  • jointplot entre nomCC1 et nomCC2 uniquement pour les Ă©tudiant(e)s dont la note au CC1 est considĂ©rĂ©e comme mĂ©diocre

pyphyschemtools.tools4AS.CreationDfADMAJGH(df, note, Seuil, prefix, MD, Parc, IDApoG)[source]
entrée :
  • df = dataframe avec les mentions/parcours/moyennes

  • note = nom de la colonne qui contient la moyenne globale

  • Seuil = seuil de rĂ©ussite pour dĂ©partager ADM & AJ

  • prefix = prĂ©fixe du nom de fichier temporaire, incluant ou nom le nom d’un sous-rĂ©pertoire de sauvegarde

  • MD = nom de la colonne qui contient la dĂ©nomination simplifiĂ©e de la mention de diplĂŽme (“MentionD”)

  • Parc = nom de la colonne qui contient le parcours

  • IDApoG = nom de la colonne qui contient l’ID des Ă©tudiants

sortie :
  • dfADM = dataframe des admis

  • dfAJ = dataframe des ajournĂ©s

  • dfGhosts = dataframe des fantĂŽmes (aka Ghosts ; i.e. n’ont passĂ© aucun des CC)

affichage : stats rapides (describe & sum) de chacun des sous-ensembles ADM, AJ, Ghosts

sauvegarde : fichier excel tmp{Note}.xlsx avec 3 onglets (ADM, AJ, Ghosts)

pyphyschemtools.tools4AS.Histogrammes(df, nomCC, Moyenne, NomGraphique, w, moy, std, moyT, stdT, legende)[source]
entrée :
  • df = dataframe qui contient ID, Noms, PrĂ©noms, notes de CC, et Moyenne pondĂ©rĂ©e

  • nomCC = liste qui contient noms d’en-tĂȘtes des colonnes qui contiennent les notes de CC

  • Moyenne = nom de l’en-tĂȘte de la colonne qui contient la moyenne

  • NomGraphique = nom du fichier png qui va contenir la figure

  • w = liste qui contient les coeffs des CC

  • moy = liste qui contient la moyenne de chaque CC

  • std = liste qui contient l’écart-type calculĂ© pour chaque CC

  • moyT = moyenne des 4 CC

  • stdT = Ă©cart-type calculĂ© pour la note globale

  • legende = titre qui sera affichĂ© sur l’histogramme principal

affichage :
  • 1 petit histogramme /CC

  • 1 grand histogramme avec la moyenne

sauvegarde :
  • fichier graphique ‘NomGraphique’ avec 1 petit histogramme par CC + 1 grand histogramme avec la moyenne

pyphyschemtools.tools4AS.MentionAuModule(note, Seuil)[source]
entrée :
  • note = valeur numĂ©rique ou NaN

  • Seuil = seuil de rĂ©ussite

sortie :
  • m = mention au module (AJ, P, AB, B, TB ou PB!! dans le cas oĂč la colonne contiendrait une valeur numĂ©rique non comprise entre 0 et 20, ou bien toute autre contenu (caractĂšres etc)

pyphyschemtools.tools4AS.RenameDfHeader(dfCC, dfCCname, labelNoteCC, nomCC)[source]
entrée :
  • dfCC = dataframe dont 1 colonne contient les notes de CC

  • dfCCname = nom (string) du dataframe. Il est recommandĂ© d’utiliser f’{dfCC=}’.split(‘=’)[0]

  • labelNoteCC = label de la colonne qui contient les notes

  • nomCC = label de l’épreuve de CC (ex CC1), utilisĂ© pour l’affichage

sortie : aucune

la fonction change le nom ‘labelNoteCC’ en ‘nomCC’

pyphyschemtools.tools4AS.ReplaceABSByNan(df, nomCC)[source]
entrée :
  • dataframe qui contient les notes

  • nom des colonnes qui contiennent les notes

sortie
  • nouveau dataframe oĂč toutes les notes des colonnes nomCC = ABS sont remplacĂ©es par des nan

pyphyschemtools.tools4AS.ReplaceNanBy0(df, nomCC)[source]
pyphyschemtools.tools4AS.ReplaceNanBy0OLD(df, nomCC)[source]
entrée :
  • df = dataframe avec les notes

  • nomCC = liste des en-tĂȘtes de colonnes qui contiennt les notes

sortie :
  • le dataframe avec Nan remplacĂ© par 0 pour chaque Ă©tudiant qui a au moins une note de CC

pyphyschemtools.tools4AS.StackedBarPop(df, ListCols, ylabel, NomGraphique)[source]
entrée :
  • df : dataframe contenant l’analyse statistique globale, dont les moyennes, effectifs, etc. i.e. le dataframe renvoyĂ© par StatsRĂ©ussiteParMentionOuParcours()

  • ListCols = liste avecles labels des colonnes contenant les valeurs numĂ©riques qu’on veut tracer comme un histogramme empilĂ©

  • ylabel = label de l’axe des y

  • NomGraphique = nom du fichier png qui va ĂȘtre sauvĂ©

affichage :
  • bar plot empilĂ© de pandas

sauvegarde :

fichier graphique ‘NomGraphique’ au format png

pyphyschemtools.tools4AS.StackedBarPopPO(dfRef, Mention, Parcours, NomGraphique)[source]
entrée :
  • dfRef : dataframe contenant la liste des Ă©tudiants avec leur Mention et leur otpion, tel que gĂ©nĂ©rĂ© par mentionD()

  • Mention = nom de la colonne qui contient le nom simplifiĂ© d’une Mention

  • Parcours = nom de la colonne qui contient la version simplifiĂ©e d’un Parcours

  • NomGraphique = nom du fichier png qui va ĂȘtre sauvĂ©

affichage :
  • histplot “hue” de seaborn, cĂ d les effectifs par Parcours empilĂ©s pour chaque Mention

sauvegarde :

fichier graphique ‘NomGraphique’ au format png

pyphyschemtools.tools4AS.StatsRéussiteParMentionOuParcours(dfT, dfADM, dfAJ, dfGhosts, Category, note)[source]
entrée :
  • dfT = dataframe qui contient toutes les notes, ainsi qu’au moins une catĂ©gorisation (exemple : Mention ou Parcours ou Section etc
)

  • dfADM = dataframe qui contient uniquement les Ă©tudiants admis

  • dfAJ = dataframe qui contient uniquement les Ă©tudiants ajournĂ©s (sans les fantĂŽmes)

  • dfGhosts = dataframe qui contient la liste des fantĂŽmes

  • Category = nom de la colonne sur laquelle on veut faire des analyses statistiques

  • note = nom de la colonne qui contient la note qu’on veut analyser par catĂ©gorie (gĂ©nĂ©ralement la moyenne finale)

sortie :
  • dfStats

affichage :

pyphyschemtools.tools4AS.StatsRéussiteParMentionOuParcoursWithAb(dfT, dfADM, dfAJ, dfGhosts, dfAb, Category, note)[source]
entrée :
  • dfT = dataframe qui contient toutes les notes, ainsi qu’au moins une catĂ©gorisation (exemple : Mention ou Parcours ou Section etc
)

  • dfADM = dataframe qui contient uniquement les Ă©tudiants admis

  • dfAJ = dataframe qui contient uniquement les Ă©tudiants ajournĂ©s (sans les fantĂŽmes)

  • dfGhosts = dataframe qui contient la liste des fantĂŽmes

  • dfAb = dataframe qui contient la liste des Ă©tudiants qui ont abandonnĂ©

  • Category = nom de la colonne sur laquelle on veut faire des analyses statistiques

  • note = nom de la colonne qui contient la note qu’on veut analyser par catĂ©gorie (gĂ©nĂ©ralement la moyenne finale)

sortie :
  • dfStats

affichage :

pyphyschemtools.tools4AS.checkNoID_DuplicateID(df, dfname, ID, nom, NomPrenom)[source]
pyphyschemtools.tools4AS.concat2ApoG(df2Complete, ID_ApoG, dfCC, Col2SaveInCC, IDCC, nomCC)[source]
entrée :
  • df2Complete = dataframe Ă  complĂ©ter (merge = ‘left’)
    • au premier appel, ce soit ĂȘtre le fichier de RĂ©fĂ©rence

    • ensuite c’est le fichier de notes lui-mĂȘme, en cours d’update

  • ID_ApoG = label de la colonne qui contient les numĂ©ros Ă©tudiants dans le fichier de rĂ©fĂ©rence

  • dfCC = dataframe dont 1 colonne contient les notes de CC

  • Col2SaveInCC = liste avec les en-tĂȘtes de colonnes qui contiennent les colonnes de dfCC Ă  reporter dans dfNotes

  • IDCC = label de la colonne qui contient les numĂ©ros Ă©tudiants dans le fichier de notes

  • nomCC = Ă  ce stade, c’est aussi bien le label de la colonne qui contient les notes que le label de l’épreuve de CC (ex CC1), utilisĂ© pour l’affichage

sortie :
  • le dataframe dfNotes. Contient la version concatĂ©nĂ©e du dataframe d’entrĂ©e df2complete et certaines colonnes du dataframe des notes dfCC ([Col2SaveInCC + IDCC + nomCC])

  • un dataframe dfnotFoundInRef qui contient la liste des Ă©tudiants qui sont dans le fichier de notes et pas dans le fichier de rĂ©fĂ©rence

affichages :
  • liste des Ă©tudiants qui sont dans le fichier de notes et pas dans le fichier de rĂ©fĂ©rence

pyphyschemtools.tools4AS.css_styling()[source]
pyphyschemtools.tools4AS.dropColumnsByIndex(df, idropC)[source]
entrée :
  • df = dataframe dont on veut supprimer des colonnes

  • idropC = indices des colonnes dont on veut se dĂ©barasser

sortie :
  • dfCleaned = dataframe originel dont les colonnes indexĂ©es par idropC ont Ă©tĂ© supprimĂ©es

pyphyschemtools.tools4AS.kdePlotByMentionEtParcours(df, Moyenne, Mention, Parcours, NomGraphique)[source]
entrée :
  • df = dataframe qui contient ID, Noms, PrĂ©noms, notes de CC, Moyenne pondĂ©rĂ©e, Mention et Parcours

  • Mention = nom de l’en-tĂȘte de la colonne qui contient la Mention de diplĂŽme simplifiĂ©e d’un Ă©tudiant

  • Parcours = nom de l’en-tĂȘte de la colonne qui contient le parcours suivi par un Ă©tudiant

affichage :
  • 1 graphe avec des plots kde par Mention

  • 1 graphe avec des plots kde par Parcours

sauvegarde :
  • fichier graphique ‘NomGraphique’ avec les 2 graphes

pyphyschemtools.tools4AS.mentionD(row, Mention)[source]
pyphyschemtools.tools4AS.parcours(row, Parcours)[source]
pyphyschemtools.tools4AS.plotTauxADMasBars(dfwoSC, dfwSC, xCol, hueCol, NomGraphique)[source]
entrée :
  • dfwoSC = dataframe contenant les stats ADM/AJ/Ghosts avant l’application de la seconde chance

  • dfwSC = dataframe contenant les stats ADM/AJ/Ghosts aprĂšs l’application de la seconde chance

  • xCol = nom de la colonne qui contient les taux de rĂ©ussite

  • hueCol = nom de la colonne qui contient les paramĂštres avant ou aprĂšs seconde chance

  • NomGraphique = nom du fichier png qui va ĂȘtre sauvĂ©

affichage :
  • bar plot de seaborn

sauvegarde :

fichier graphique ‘NomGraphique’ au format png

pyphyschemtools.tools4AS.read_excel(xlFile, decimal, name)[source]
entrée :
  • xlFile = nom du ficher excel

  • decimal = “.” ou “,” selon le cas

  • name = label du dataframe, utilisĂ© pour l’affichage

sortie :
  • le dataframe qui contient l’intĂ©gralitĂ© du fichier excel

  • le nombre de lignes de ce tableau (Ă  l’exclusion de l’en-tĂȘte des colonnes)

affichage :
  • statistiques descriptives (describe) de toutes les colonnes, y compris celles qui ne contiennent pas de valeurs numĂ©riques

pyphyschemtools.tools4AS.verifNotes(dfCC, labelNoteCC, nomCC, NI, absents='aabs')[source]
Parameters:
  • CC (- nomCC = label de l'Ă©preuve de)

  • notes (- labelNoteCC = label de la colonne qui contient les)

  • CC

  • module (- NI = nombre d'inscrits dans le)

  • absents (-) –

    • ‘aabs’ : analyser s’il y a des Ă©tudiants qui n’ont pas Ă©tĂ© pointĂ©s au CC (dĂ©faut)

    • ’noabs’ne pas analyser s’il y a des Ă©tudiants qui n’ont pas Ă©tĂ© pointĂ©s au CC

      (ça n’a plus de sens une fois les fichiers concatĂ©nĂ©s)

Returns:

  • la moyenne et la dĂ©viation standard de liste de notes contenues dans le dataframe dfCC

  • le nombre d’étudiants qui n’ont pas composĂ© au CC

Note

Affiche le nombre d’étudiants avec le label ‘ABS’ et signale les Ă©tudiants sans note ni label, ce qui nĂ©cessite une vĂ©rification du PV.

pyphyschemtools.units module

class pyphyschemtools.units.Area(value, unit='m2')[source]

Bases: PhysicalQuantity

Area management. Supports SI and Si-related units (m2, hectare) and Imperial units (sq inch, sq ft, acre).

to(target)[source]
class pyphyschemtools.units.Density(value, unit='kg/cm3')[source]

Bases: PhysicalQuantity

Density (Mass per Volume) management. Supports SI (kg/m3) and common lab units (g/cm3, g/mL, lb/ft3).

to(target)[source]
class pyphyschemtools.units.Energy(value, unit='J')[source]

Bases: PhysicalQuantity

to(target)[source]
class pyphyschemtools.units.Length(value, unit='m')[source]

Bases: PhysicalQuantity

Distance and Length management. Supports SI (m) and Imperial units (inch, foot, yard, mile, nautical mile).

to(target)[source]
class pyphyschemtools.units.Mass(value, unit='kg')[source]

Bases: PhysicalQuantity

Mass management.

to(target)[source]
class pyphyschemtools.units.MolarMass(value, unit='kg/mol')[source]

Bases: PhysicalQuantity

Molar Mass management for chemical species. Converts between g/mol, kg/mol, and Da (Daltons/amu).

to(target)[source]
class pyphyschemtools.units.PhysicalQuantity(value, unit, conversion_map)[source]

Bases: object

classmethod parse(query)[source]

Parses strings like ‘13.6 eV’ or ‘1013 hPa’.

static show_available_prefixes()[source]

Displays a styled table of all supported SI prefixes (symbol, factor, SI prefix name, French and English names).

classmethod show_available_units()[source]

Displays available base units, underlining the SI base unit (factor 1.0).

static show_constants_metadata()[source]

Displays a styled table of the physical constants used for calculations, including CODATA values, units, and uncertainties.

class pyphyschemtools.units.Pressure(value, unit='Pa')[source]

Bases: PhysicalQuantity

Pressure management class (Pa, bar, atm, torr, psi).

to(target)[source]
class pyphyschemtools.units.Temperature(value, unit='K')[source]

Bases: PhysicalQuantity

classmethod show_available_units()[source]

Displays available temperature units as a styled DataFrame, highlighting Kelvin in blue.

to(target)[source]

Converts the absolute temperature to a target scale.

class pyphyschemtools.units.Volume(value, unit='m3')[source]

Bases: PhysicalQuantity

Volume management. Supports SI and SI-related units (m3, L) and Imperial units (gallon, quart, pint, fluid ounce). Note: Uses US liquid measures from SciPy.

to(target)[source]

pyphyschemtools.visualID module

pyphyschemtools.visualID.chrono_show()[source]
pyphyschemtools.visualID.chrono_start()[source]
pyphyschemtools.visualID.chrono_stop(hdelay=False)[source]
class pyphyschemtools.visualID.color[source]

Bases: object

BLUE = '\x1b[94m'
BOLD = '\x1b[1m'
CYAN = '\x1b[96m'
DARKCYAN = '\x1b[36m'
GREEN = '\x1b[92m'
OFF = '\x1b[0m'
PURPLE = '\x1b[95m'
RED = '\x1b[91m'
UNDERLINE = '\x1b[4m'
YELLOW = '\x1b[93m'
pyphyschemtools.visualID.css_styling(pwy)[source]
pyphyschemtools.visualID.display_md(text)[source]
pyphyschemtools.visualID.end(pwy)[source]
pyphyschemtools.visualID.hdelay(sec)[source]
pyphyschemtools.visualID.hdelay_ms(delay)[source]
pyphyschemtools.visualID.init(pwy)[source]

pyphyschemtools.visualID_Eng module

pyphyschemtools.visualID_Eng.apply_css_style()[source]

Explicitly reads and applies the visualID CSS stylesheet from the package resources.

class pyphyschemtools.visualID_Eng.bg[source]

Bases: object

DARKRED = '\x1b[38;5;231;48;5;52m'
DARKREDB = '\x1b[38;5;231;48;5;52;1m'
LIGHTBLUE = '\x1b[48;5;117m'
LIGHTBLUEB = '\x1b[48;5;117;1m'
LIGHTGREEN = '\x1b[48;5;156m'
LIGHTGREENB = '\x1b[48;5;156;1m'
LIGHTRED = '\x1b[48;5;217m'
LIGHTREDB = '\x1b[48;5;217;1m'
LIGHTYELLOW = '\x1b[48;5;228m'
LIGHTYELLOWB = '\x1b[48;5;228;1m'
OFF = '\x1b[0m'
pyphyschemtools.visualID_Eng.chrono_show()[source]
pyphyschemtools.visualID_Eng.chrono_start()[source]
pyphyschemtools.visualID_Eng.chrono_stop(hdelay=False)[source]
class pyphyschemtools.visualID_Eng.color[source]

Bases: object

BLUE = '\x1b[94m'
BOLD = '\x1b[1m'
CYAN = '\x1b[96m'
DARKCYAN = '\x1b[36m'
GREEN = '\x1b[92m'
OFF = '\x1b[0m'
PURPLE = '\x1b[95m'
RED = '\x1b[91m'
UNDERLINE = '\x1b[4m'
YELLOW = '\x1b[93m'
pyphyschemtools.visualID_Eng.display_md(text)[source]
pyphyschemtools.visualID_Eng.end()[source]

Terminates the notebook session: displays duration, end time, and the termination logo from package resources.

class pyphyschemtools.visualID_Eng.fg[source]

Bases: object

BLACK = '\x1b[30m'
BLUE = '\x1b[94m'
CYAN = '\x1b[96m'
DARKCYAN = '\x1b[36m'
DARKGRAY = '\x1b[90m'
GREEN = '\x1b[92m'
LIGHTGRAY = '\x1b[37m'
OFF = '\x1b[0m'
PURPLE = '\x1b[95m'
RED = '\x1b[91m'
WHITE = '\x1b[38;5;231m'
YELLOW = '\x1b[93m'
pyphyschemtools.visualID_Eng.hdelay(sec)[source]
pyphyschemtools.visualID_Eng.hdelay_ms(delay)[source]
class pyphyschemtools.visualID_Eng.hl[source]

Bases: object

BLINK = '\x1b[5m'
BOLD = '\x1b[1m'
ITALIC = '\x1b[3m'
OFF = '\x1b[0m'
UNDERL = '\x1b[4m'
blink = '\x1b[25m'
bold = '\x1b[21m'
italic = '\x1b[23m'
underl = '\x1b[24m'
pyphyschemtools.visualID_Eng.init(which=None)[source]

Initializes the notebook environment: applies CSS, displays the banner, and shows hostname/time.