HMO documentation
Hückel Molecule Drawer & Solver (HMO Tool)
This program provides a complete graphical interface for the interactive construction of (planar π-conjugated) molecules and the analysis of their molecular orbitals using the Hückel model. It allows the user to draw the molecular skeleton on a grid, select atom types (C·, N:, O·, etc.), add bonds, and perform a full Hückel analysis that includes:
generation of the Hückel matrix,
solving for orbital energies (eigenvalues),
calculating the molecular orbital coefficients (eigenvectors),
determining π-charges on atoms and π-bond orders,
computing global descriptors: total energy, HOMO-LUMO gap, hardness, chemical potential, etc.
Main features:
Manual construction of the molecular skeleton (adding/removing atoms and bonds),
Saving and loading the sigma skeleton of molecules (.hmo format),
Running Hückel analysis and directly visualizing results,
Exporting complete results (MO coefficients, π-charges, bond orders, descriptors) to Excel or PDF,
Graphical visualization of molecular orbitals (shapes and energies) in a dedicated window.
Display organization (Tkinter-based):
The program is built with the Tkinter library, which manages all graphical interfaces:
- Molecule Drawer (main window):
Handled by the MoleculeDrawer class, this main window (based on Tk()) contains:
Left section: a Canvas where the user builds the molecule (grid, atoms, bonds),
- Right section: a toolbar with buttons for main actions (run analysis, save/load molecule,
access visualizations, export data).
- HMO Viewer (dedicated MO visualization window):
Instantiated by the HMOViewer class when the user clicks the visualization button.
This secondary window uses Toplevel to open independently.
- It displays:
an energy diagram (MO energy levels),
graphical representations of occupied and virtual orbitals,
a miniature view of the molecule to show its overall topology.
- Numerical Results Window:
Managed by the ResultsViewer class and also opened via Toplevel.
- Displays:
molecular orbital coefficients in a table format,
π-charges, π-bond orders,
global descriptors (total energy, HOMO-LUMO gap, etc.).
Usage:
The user starts by constructing the molecule, then runs the Hückel analysis. After computation, results can be explored numerically (ResultsViewer window) and graphically (HMOViewer window), and exported. The graphical visualization allows easy exploration of molecular orbitals and their energy levels.

Using the Molecule Builder:
- Basic Drawing Rules
By default, all atoms are carbon (C·) unless modified.
- A bond can be created between two atoms by:
Clicking and dragging from one atom to a new position >> this adds a new carbon atom connected by a bond.
Clicking and dragging from one atom to another existing atom >> this creates a bond between the two.
- Atom Customization
- Right-click on an atom to open a context menu.
You can change the atom type to one of the predefined atoms with parameterized Hückel integrals.
(!) Warning: not all combinations are fully defined - if a bond between two atom types lacks a known kXY parameter, the Hückel matrix may be incomplete or raise a warning.
- Charges
You can add a formal charge using the “Add a charge” tool in the toolbar.
Right-clicking on a charge opens a dialog box to edit its value (e.g. change from -1 to +1).
Notes:
Most graphical interactions (atom placement, bond drawing) are done with the mouse, with keyboard shortcuts for efficiency.
The program is structured around the main classes: MoleculeDrawer (main interface), HMOViewer (MO visualization), ResultsViewer (numerical results), Node (management of individual atoms), ChargeNode (management of the global charge, which is 0 y default), and ToolTip (management of tooltips for the icons of the main window).
Hückel parameters and some visualization settings are defined in the HuckelParameters class
Visualization and layout parameters for the HMOViewer interface are provided by the HMOViewerParameters class
- class hmo.HMO.ChargeNode(x, y, charge='-1')
Represents a charge element on the canvas that cannot form bonds. It has a visual indicator (colored disk with sign), and affects the total number of π electrons.
- charge_radius = 15
- contains(x, y)
Checks if a point (x, y) lies within the charge disk (used for click detection).
- draw(canvas, x=None, y=None)
Draws the charge on the canvas. Uses scaled x/y if provided.
- class hmo.HMO.HMOViewer(master, df_atoms, df_global_charges, df_bonds, df_MOs, df_descriptors, project_name)
GUI application for visualizing Hückel Molecular Orbitals (MOs) and their energy diagrams.
This class provides a graphical interface to render the molecular structure and the associated energy levels of the molecular orbitals (occupied and virtual). It allows the user to explore the molecule’s π-system, display orbital diagrams, adjust visualization parameters in real time, and save high-quality images.
- Parameters:
master (tk.Toplevel or tk.Tk) – The parent Tkinter window that contains the interface.
df_atoms (pd.DataFrame) – DataFrame containing atomic positions, indices, and element types.
df_global_charges (pd.DataFrame) – DataFrame containing global charges positions and values
df_bonds (pd.DataFrame) – DataFrame specifying bonds between atoms (indices and bond order).
df_MOs (pd.DataFrame) – DataFrame containing molecular orbital coefficients for each atom in the system.
df_descriptors (pd.DataFrame) – DataFrame containing computed molecular descriptors (e.g., number of π electrons, symmetry).
project_name (str) – Name of the current project, used in window titles and when saving files.
- canvas
The canvas widget where the molecule and energy levels are drawn.
- Type:
tk.Canvas
- scale_slider
Slider widget that allows dynamic adjustment of the overall molecular diagram scale (×0.5 to ×3.0).
- Type:
tk.Scale
- lobe_slider
Slider widget that allows dynamic adjustment of orbital lobe sizes (×0.7 to ×1.3).
- Type:
tk.Scale
- homo_lumo_button
Button that resets the view to the default HOMO and LUMO orbitals.
- Type:
tk.Button
- skeleton_button
Button to toggle skeleton-only mode (hide or show atom labels).
- Type:
tk.Button
- save_button
Button to save the full diagram as a high-quality PNG image.
- Type:
tk.Button
- close_button
Button to close the viewer window.
- Type:
tk.Button
- show_atom_labels
Tracks whether atom labels are displayed in the skeleton overview.
- Type:
bool
- skeleton_items
List of graphical items representing the skeleton; used for easy refresh.
- Type:
list
- user_scale_multiplier
Multiplier applied to the default molecule scaling (set by the scale_slider).
- Type:
float
- user_lobe_multiplier
Multiplier applied to the orbital lobe scaling (set by the lobe_slider).
- Type:
float
Notes
Energy levels can be clicked to view individual MOs.
The visualization is interactive: adjusting sliders immediately refreshes the displayed orbitals.
Pressing the Escape key closes the viewer.
Example
>>> root = tk.Tk() >>> viewer = HMOViewer( ... master=root, ... df_atoms=df_atoms, ... df_global_charges=df_global_charges, ... df_bonds=df_bonds, ... df_MOs=df_mos, ... df_descriptors=df_descriptors, ... project_name="Benzene" ... ) >>> root.mainloop()
The window opens showing the molecular diagram and energy levels.
Click the “HOMO/LUMO” button to quickly reset the view.
Adjust the “Molecule Scale” and “Lobe Scale” sliders to change the diagram in real-time.
Save the diagram using the “Save as PNG” button.
Close the window by pressing Escape or clicking “Close”.
- display_default_homo_lumo()
Automatically displays the HOMO and LUMO orbitals by detecting their indices.
This method: - Identifies the highest occupied molecular orbital (HOMO) and the lowest unoccupied molecular orbital (LUMO). - Displays the HOMO in the occupied frame and the LUMO in the virtual frame.
Notes
If no HOMO or LUMO is found, nothing is displayed for that type.
- display_mo(idx, occupied=True)
Displays a specific molecular orbital (MO) in its corresponding frame (occupied or virtual).
This method draws the selected MO, including bonds and orbital lobes, in the appropriate frame (HOMO or LUMO area), scaled and centered within the available space. The visualization responds dynamically to user-controlled scaling factors from the sliders: - ‘Molecule Scale’ slider: adjusts the overall size of the molecule, - ‘Lobe Scale’ slider: adjusts the relative size of the orbital lobes.
- Parameters:
idx (int) – The index of the MO to display.
occupied (bool, default=True) – Whether the MO is an occupied orbital (True) or a virtual one (False).
Notes
Centers and scales the molecule to fit inside its frame.
Draws bonds and orbital lobes, with size and color depending on MO coefficients.
Adds atom labels if ‘Skeleton Only’ mode is off.
The user-defined scaling factors (sliders) affect both molecule size and lobe size in real time.
Handles rendering of both positive (red) and negative (blue) lobes with layered drawing.
- draw_energy_levels()
Draws all energy levels (molecular orbitals) in the diagram.
Each energy level: - Is represented as an image (usually a line or bar). - Is grouped if degenerate (multiple orbitals with same energy). - Shows electron occupancy via additional graphical indicators (2e or 1e overlays).
Notes
Binds a click event to each energy level image so that clicking an MO updates the orbital display (via on_level_click).
- draw_energy_scale_and_descriptors(min_e, max_e, scale, energies_sorted)
Draws the energy scale, horizontal dotted guide lines, and key descriptors under the MO diagram.
- Parameters:
min_e (float) – The minimum energy value in the set of molecular orbitals.
max_e (float) – The maximum energy value.
scale (float) – The vertical scaling factor to convert energy values to pixel positions.
energies_sorted (list) – Sorted list of energy values (from high to low).
Notes
Adds a vertical energy scale with an arrow, horizontal guide lines at regular energy steps, and labels each line with its corresponding (α + β) expression.
Displays summary descriptors like total energy, atomization energy, HOMO-LUMO gap, and hardness.
- draw_layout()
Draws the main layout of the viewer interface.
This includes: - The project name at the top. - Two frames: one for virtual MOs (LUMO and above) and one for occupied MOs (HOMO and below). - Labels for each section. - An overview area to display a miniaturized version of the molecular skeleton under the MO diagram.
Notes
The overview area is scaled to fit the available space and is drawn using draw_skeleton_overview.
- draw_skeleton_overview(x0, y0, width, height)
Draws a miniaturized version of the full molecule in a dedicated area under the MO diagram.
- Parameters:
x0 (int) – The x-coordinate of the top-left corner of the drawing area.
y0 (int) – The y-coordinate of the top-left corner.
width (int) – The width of the available area.
height (int) – The height of the available area.
Notes
Automatically scales the molecule to fit the provided area.
Displays bonds and atoms; optional atom labels are shown if self.show_atom_labels is True.
- load_images()
Loads and resizes graphical assets used in the MO diagram.
This method retrieves three image resources: - 1e.png : icon for singly occupied MO, - 2e.png : icon for doubly occupied MO, - energy_level.png : horizontal energy level bar.
The images are resized to appropriate dimensions and stored as Tkinter-compatible PhotoImage objects.
- on_escape(event)
Callback triggered when the Escape key is pressed.
This method gracefully closes the application window by destroying the root Tkinter widget.
- Parameters:
event (tkinter.Event) – The keypress event object (not used directly).
- on_level_click(idx)
Callback when a molecular orbital energy level is clicked in the diagram.
- Parameters:
idx (int) – The index of the clicked MO.
Notes
Determines if the MO is occupied or virtual based on its occupancy.
Updates the corresponding frame to display the clicked orbital using display_mo.
- prepare_data()
Extracts MO energies and occupations from column headers and prepares data for rendering.
- Parses each MO column label in self.df_MOs to extract:
The energy coefficient (in units of β),
The number of electrons (occupation).
Computes the global max coefficient for scaling orbital display.
Calculates the mean bond length for graphical positioning.
Groups MOs by energy (rounded to 5 decimal places) into self.energy_groups.
Notes
Assumes that column headers follow the format: “MO = -1.25βn2e” or similar.
Uses helper function compute_mean_bond_length() for estimating bond scaling.
The resulting attributes are: - self.energies : list of float (one per MO), - self.occupations : list of int (0, 1, 2), - self.max_coef_global : float, used for visual scaling, - self.mean_bond_length : float, used to normalize drawing, - self.energy_groups : dict mapping rounded energy >> list of MO indices.
- refresh_MOs()
Redraws the currently displayed molecular orbitals (HOMO & LUMO by default).
- refresh_skeleton()
Clears and redraws the full molecular skeleton.
- save_canvas_as_png()
Save the full canvas as a high-resolution PNG image.
- toggle_skeleton()
Toggle the skeleton-only mode (with or without atom labels).
- class hmo.HMO.MoleculeDrawer(master)
GUI application for drawing molecules and performing Hückel Molecular Orbital (HMO) calculations and analysis.
The MoleculeDrawer class provides an interactive graphical interface that allows the user to build a molecular structure by placing atoms and bonds on a grid. It supports the customization of atom types, and includes functionalities to save/load molecules, undo/redo actions, and erase atoms or bonds.
Once a molecule is built, the tool can run a Hückel analysis to compute molecular orbital energies, coefficients, π-charges, and π-bond orders. Results are displayed numerically and graphically, with options to save data as Excel files or images.
- Parameters:
master (tk.Tk or tk.Toplevel) – The root window or parent window that holds the GUI.
- bonds
The list of bonds, each defined by a tuple of two node indices.
- Type:
list of tuple
- undo_stack
A stack to store the history of molecule states for undo functionality.
- Type:
list
- redo_stack
A stack to store undone actions for redo functionality.
- Type:
list
- df
The main DataFrame containing molecular orbital coefficients.
- Type:
pd.DataFrame or None
- df_atoms
DataFrame containing atom types, coordinates, and π charges.
- Type:
pd.DataFrame or None
- df_bonds
DataFrame listing bonds between atoms.
- Type:
pd.DataFrame or None
- df_summary
DataFrame summarizing molecular descriptors (energy, hardness, gap, etc.).
- Type:
pd.DataFrame or None
- project_name
The user-defined name of the current project.
- Type:
str or None
- safe_project_name
A sanitized version of the project name (safe for filenames).
- Type:
str or None
- mo_viewer_window
The window displaying molecular orbital visualizations.
- Type:
tk.Toplevel or None
- om_window
The window showing numerical molecular orbital data.
- Type:
tk.Toplevel or None
Notes
The interface includes a toolbar with buttons for running the Hückel analysis, saving/loading molecules, exporting results, and accessing help/about information.
Huckel parameters (α and β) are set by default to -11.0 and -2.7 but can be modified in the code.
The program supports exporting results as .xlsx files (multi-sheet Excel) and visual representations as .png or .pdf.
The tool can gracefully handle molecule resizing and grid alignment, making drawing easy.
Examples
>>> root = tk.Tk() >>> app = MoleculeDrawer(root) >>> root.mainloop()
- apply_scale(x, y)
- bind_shortcuts()
Bind keyboard shortcuts (Ctrl + key) to main application actions.
Shortcuts include: - Ctrl+R : Run Hückel calculation - Ctrl+S : Save molecule - Ctrl+O : Load molecule - Ctrl+Z : Undo - Ctrl+Y : Redo - Ctrl+D : Clear canvas - Ctrl+P : Export all results to PDF - Ctrl+L : Save data to spreadsheet - Ctrl+Q : Quit program - Ctrl+H : Show ‘About’ window
- build_dataframes()
Builds and updates key DataFrames summarizing the molecule’s structural and electronic properties.
This method generates and assigns four main DataFrames: 1. df_bond_orders_matrix: A symmetric matrix showing π-bond orders between all atom pairs. 2. df_atoms: A table containing atom indices, types, positions (grid units), π charges, and colors. 3. df_bonds: A table listing all bonds between atoms with atom labels. 4. df_summary: A summary table of molecular descriptors, such as total π-electron energy, HOMO-LUMO gap, chemical potential, hardness, softness, and electrophilicity. 5. df_global_charges: A table of manually placed formal charges, including position and value; or empty if none.
The resulting DataFrames are stored as attributes for export or display in other parts of the application.
- Returns:
None
(The method updates internal attributes (df_bond_orders_matrix, df_atoms, df_bonds, df_summary and df_global_charges))
Notes
Atom labels are formatted as ‘<AtomType><Index>’ (e.g., ‘C·1’, ‘O:2’).
Bond orders are rounded to 3 decimal places.
π charges are computed from Hückel analysis results and rounded to 3 decimal places.
The summary DataFrame expresses all energy-related descriptors in units of β (or multiples/fractions thereof).
The method assumes that the Hückel analysis (and charge/bond order computation) has already been performed.
df_global_charges will contain user-defined formal charges if any have been placed in the GUI.
Example
>>> mol = MoleculeDrawer(root) >>> mol.build_dataframes()
The following attributes are now available: - mol.df_bond_orders_matrix - mol.df_atoms - mol.df_bonds - mol.df_summary - mol.df_global_charges
- build_huckel_matrix(alpha=0.0, beta=-1.0)
Constructs the Hückel matrix (Hamiltonian) for the current molecular graph.
This method builds the square matrix H of size n×n, where n is the number of atoms (nodes) in the molecule. The diagonal elements (alpha) represent Coulomb integrals, while the off-diagonal elements (beta) represent resonance integrals between bonded atoms.
Atomic parameters are retrieved from the Huckel_atomic_parameters dictionary using the atom’s type (e.g., ‘C’, ‘N’, etc.), and bond parameters are retrieved from the Huckel_kXY_parameters dictionary to handle heteroatomic systems with scaling factors.
- Parameters:
alpha (- alpha_part = n_pi_total *) – The Coulomb integral (diagonal value), default is 0.
beta (The entire matrix is divided by) – The resonance integral (off-diagonal value), default is -1.
Note
-----
change (The Hückel matrix H is transformed using the standard variable) – x = (alpha - epsilon) / beta
origin. (where x = 0 is chosen as the energy)
beta
beta. (so all energies (eigenvalues) are expressed in units of)
transformation. (Alpha is conceptually shifted to zero during this)
into (The total π-electron energy is separated)
alpha
units) (- beta_part = sum of occupied eigenvalues (in beta)
- Returns:
np.ndarray – The n×n Hückel matrix, where n is the number of atoms in the molecule.
Error Handling
————–
- If an atom type is not recognized or has no defined alpha parameter, an error message – is shown and the program exits.
- If a bond type is not recognized or has no defined beta parameter, an error message – is shown and the program exits.
Notes
The Huckel_atomic_parameters dictionary must provide a valid alpha_expr for each atom type involved in the molecule.
The Huckel_kXY_parameters dictionary must provide scaling factors for bonds between different atom types (e.g., C-N, C-O).
The method evaluates alpha expressions using the self.evaluate() method, which substitutes the global alpha and beta values.
Example
>>> H = drawer.build_huckel_matrix(alpha=-11.0, beta=-2.7) or H = drawer.build_huckel_matrix(alpha=0, beta=-1) in reduced units
- change_atom_type(idx, new_type)
- clear()
- compute_charges_and_bond_orders(eigvecs, occupation_dict)
Compute atomic π-charges and π-bond orders from Hückel eigenvectors.
This method evaluates: - The π-charge on each atom, as the difference between its formal π-electrons and the Mulliken-like population derived from the eigenvector coefficients. - The π-bond order between each pair of bonded atoms, as a weighted sum of the products of their orbital coefficients across all occupied molecular orbitals.
- Parameters:
eigvecs (ndarray (n_atoms, n_orbitals)) – Matrix of eigenvectors (molecular orbital coefficients) from the Hückel diagonalization. Each column corresponds to an orbital; each row to an atom.
occupation_dict (dict) – Dictionary mapping orbital indices to their occupation numbers (e.g., 2 or 0).
- Returns:
charges (list of float) – The computed π-charge for each atom, in the same order as self.nodes.
bond_orders (dict) – A dictionary with keys as (i, j) tuples (atom indices of bonded pairs) and values as the computed π-bond order between those atoms.
Notes
The method assumes that each atom’s expected number of π-electrons (n_pi) is defined in HuckelParameters.Huckel_atomic_parameters.
The bond list self.bonds should contain tuples of bonded atom indices.
- count_bonds(idx)
- create_button(icon, command, tooltip)
Create a single button for the toolbar with icon, command, and tooltip.
- Parameters:
icon (PhotoImage) – The icon image to display on the button.
command (callable) – The function to execute when the button is clicked.
tooltip (str) – The tooltip text displayed on hover, and temporarily shown in the window title.
- Returns:
The created Tkinter Button widget.
- Return type:
tk.Button
- create_toolbar()
Create the main toolbar with all interactive buttons.
This method creates buttons for key actions such as running the Hückel calculation, saving/loading the molecule, undo/redo, charge placement, numerical output, exporting results, and quitting the program. Each button is associated with an icon and a tooltip.
- delete_node(idx)
- draw_grid()
- evaluate(expr, alpha, beta)
- export_all_results_to_pdf()
- find_bond(x, y)
- find_node(x, y)
- find_node_by_coords(x_grid, y_grid)
- left_click(event)
- load_icons()
Load toolbar icons from the icons-logos-banner folder.
This method populates self.icons with PhotoImage objects keyed by function names. These icons are later used to create toolbar buttons.
- load_molecule()
Load a molecular structure from a .hmo file.
This method opens a file dialog prompting the user to select a .hmo file. It reads the file content and reconstructs the molecule by: - Parsing the “Nodes:” section to recreate the list of atoms (self.nodes). - Parsing the “Bonds:” section to recreate the list of bonds (self.bonds).
The current state is first saved (for undo purposes), and the canvas is redrawn after loading. If an error occurs (e.g., corrupted file), an error message is shown.
Notes
The expected format of the file is: Nodes: AtomType x y … Bonds: i j …
- mouse_drag(event)
- mouse_motion(event)
- mouse_release(event)
- node_exists_at(x, y)
- on_run_huckel()
Executes the full Hückel analysis workflow.
This method performs the following steps:
1️⃣ Runs the Hückel analysis on the current molecular structure.
2️⃣ Prompts the user for a project name (default: “my_molecule”) to label results and files.
3️⃣ Sanitizes the project name for safe file usage.
- 4️⃣ Builds internal DataFrames:
Molecular orbital coefficients,
Atom-level data,
Bond list and bond orders,
Summary descriptors (energies, HOMO-LUMO gap, etc.).
5️⃣ (Optional) Displays debug printouts for DataFrame shapes.
6️⃣ Opens a new Tkinter window (HMOViewer) to visualize the molecular orbitals, atoms, bonds, and descriptors graphically.
Notes
The visualizer window (HMOViewer) is initialized with all computed data for interactive exploration.
The project name is reused as a base name for saving exports (Excel, PDF, etc.).
Debug information about DataFrame shapes is printed to the console for traceability.
- props(eigvals, occupation_dict)
Compute global energetic and chemical descriptors from Hückel eigenvalues.
This method calculates the total π-electron energy of the molecule, decomposed into its alpha (on-site) and beta (interaction) parts, as well as the atomization energy (difference between the total π-energy and the isolated atom contributions).
It also computes key global descriptors: - HOMO-LUMO gap - chemical potential (mu) - chemical hardness (eta) - softness (1/eta) - electrophilicity index (omega)
- Parameters:
eigvals (array-like) – The eigenvalues (orbital energies) from the Hückel matrix diagonalization.
occupation_dict (dict) – A dictionary mapping orbital indices to their occupation numbers (typically 2 for occupied, 0 for virtual).
Notes
This method updates instance attributes: total_energy, alpha_part, beta_part, atomization_energy, atomization_energy_per_atom, homo_lumo_gap, mu, eta, softness, omega.
Includes debug print statements for tracing the calculation steps.
- quit_program()
Prompt the user to confirm before quitting the application.
If the user confirms, the main Tkinter window is closed.
- redo()
- redraw()
Redraws the full molecular canvas, including grid, atoms, and bonds.
This method is responsible for updating the Tkinter canvas whenever the molecule’s structure changes or when the user interacts (e.g., dragging, erasing).
It handles:
1️⃣ Redrawing the base grid (for alignment).
- 2️⃣ If dragging:
Displays a highlighted grid cell (orange) under the current mouse position.
Draws a temporary dashed bond between the selected node and the cursor.
- 3️⃣ Highlights:
If in eraser mode, highlights the node or bond under the mouse cursor in red.
- 4️⃣ Bonds:
Draws all bonds as lines between atoms, with special highlighting for bonds targeted by the eraser.
- 5️⃣ Atoms:
Draws each atom as a colored circle, using the atom type’s color code.
Highlights atoms under the eraser with a red border.
Displays the atom label (type) centered in each circle.
Notes
This method fully clears the canvas before redrawing.
Visual cues (colors, highlights) guide user interaction for precision editing.
Grid snapping ensures precise atom placement during drawing.
- resize_canvas(event)
- right_click(event)
- run_huckel_analysis()
Executes the full Hückel Molecular Orbital (HMO) analysis for the current molecule.
This method performs the following steps: 1. Builds the Hückel matrix using build_huckel_matrix. 2. Solves for molecular orbital energies and coefficients (eigenvalues and eigenvectors). 3. Counts the total number of π-electrons based on atomic types. 4. Computes the occupation numbers for each molecular orbital, handling degeneracies. 5. Calculates π-electron charges and π-bond orders using the eigenvectors and occupations. 6. Updates molecular properties and builds a DataFrame of orbital coefficients for display.
The analysis assumes default Hückel parameters (alpha = -11.0, beta = -2.7) unless specified otherwise when building the matrix.
Notes
Atoms and bonds are validated to ensure parameters exist in the Huckel parameter dictionaries.
If any atom or bond type is unknown, an error message is displayed and the program exits.
Degenerate orbitals are handled by grouping them within a numerical tolerance (1e-5 by default).
Attributes Updated
- dfpd.DataFrame
A DataFrame showing molecular orbital coefficients, sorted by energy levels.
- chargeslist of float
List of π-electron charges on each atom.
- bond_ordersdict
Dictionary with keys as (i, j) tuples (atom indices) and values as bond orders.
- total_pi_electronsint
The total number of π-electrons in the molecule.
- alpha_valuefloat
The alpha value used for the current Hückel analysis.
- beta_valuefloat
The beta value used for the current Hückel analysis.
Error Handling
Unknown atom types or missing parameters in Huckel_atomic_parameters trigger an error.
Unknown bond types or missing parameters in Huckel_kXY_parameters also trigger an error.
In both cases, a messagebox error is shown, and the program exits gracefully.
Example
>>> MoleculeDrawer.run_huckel_analysis()
- sanitize_filename(name)
Sanitize a string to make it safe for use as a filename.
Replaces characters that are invalid in most file systems (such as / : * ? “ < > |) with underscores.
- Parameters:
name (str) – Original file name or label.
- Returns:
Sanitized version of the string with forbidden characters replaced.
- Return type:
str
- save_data()
- save_dataframe_as_pdf(win)
- save_dataframe_as_xlsx(win)
Export multiple pandas DataFrames to an Excel workbook with styled headers.
This method saves the following DataFrames to separate sheets in a single Excel file: - self.df_atoms: Atom-level data (sheet ‘Atoms’) - self.df_global_charges: A table of manually placed formal charges, including position and value; or empty if none. - self.df_bonds: Bond list (sheet ‘Bond List’) - self.df: Molecular orbital coefficients (sheet ‘MO Coefficients’) - self.df_bond_orders_matrix: π-bond order matrix (sheet ‘π-bond orders’) - self.df_summary: Molecular descriptors (sheet ‘Descriptors’)
The user is prompted to select a save location via a file dialog. After saving, the header row of the ‘MO Coefficients’ sheet is styled with text wrapping.
- Parameters:
win (tkinter.Tk or tkinter.Toplevel) – The parent window for the file dialog.
- Returns:
True if the file was successfully saved, False otherwise (e.g., if the user cancels).
- Return type:
bool
Notes
If no data is available (DataFrames are None), a warning dialog is shown.
The Excel file is saved with the ‘.xlsx’ extension, and the default filename is based on self.safe_project_name.
- save_molecule()
Save the current molecular structure to a .hmo file.
This method opens a file dialog prompting the user to select the save location. The molecule is saved in a simple text format: - A “Nodes:” section listing each atom with its type and (x, y) grid coordinates. - A “Bonds:” section listing each bond as pairs of atom indices.
If a project name is available (self.safe_project_name), it is used as the default filename.
Notes
The saved file allows reloading the same molecular structure later using load_molecule.
- save_state()
- set_mode_add_charge()
Sets the current interaction mode to adding a new charge.
- show_about()
Display the ‘About’ window for the HMO application.
This window shows: - A banner/logo loaded from ‘icons-logos-banner/HMO_Banner.png’, - The author’s address and credits, - The current version of the application, - A ‘Close’ button to dismiss the window.
The window is non-resizable and can also be closed using the Escape key.
- show_charge_bond_view()
Displays the molecule using matplotlib in a Tkinter window with atom colors, formal charges, and π bond indices. Includes buttons to save (PNG, SVG, PDF, EPS) and close.
- show_dataframe_in_window()
Display molecular orbital coefficients, a molecular diagram, and key descriptors in a new window.
This method creates a Tkinter Toplevel window that presents:
[1] A scaled 2D visualization of the molecule (atoms and bonds), centered in a canvas.
- [2] A summary section with computed descriptors:
Total π-electron energy,
Number of π electrons,
Atomization energy (absolute and per atom),
HOMO-LUMO gap,
Chemical potential (μ),
Hardness (η),
Softness (S),
Electrophilicity index (ω).
- [3] A scrollable table that displays the molecular orbital (MO) coefficients.
The table is split into two Treeviews: one for the index column, one for the data.
Scrollbars (vertical and horizontal) are shared between the two views for smooth scrolling.
The visualization includes: - Atoms drawn as colored circles (color based on ATOM_COLORS), - Atom labels with their type and index, - Bonds drawn as black lines.
Features:
The molecular diagram is auto-scaled to fit the canvas, with debug prints for scaling details.
The summary text is stored in self.summary_text for potential later use (e.g., export).
If a previous window (self.om_window) is still open, it is closed before opening the new one.
An Escape key binding allows closing the window quickly.
Notes:
The descriptors use self.alpha_value and self.beta_value for normalization.
Treeviews are laid out side-by-side: the index column remains fixed, while data columns can expand.
This window is meant as an interactive, visual companion to numerical data (e.g., after Hückel analysis).
Shortcut:
Pressing Esc closes the window.
- show_numerical_data()
- snap_to_grid(x, y)
- toggle_eraser()
Toggle eraser mode on or off.
When enabled, the application allows the user to delete atoms or bonds by clicking. This method also updates the background color of the eraser button to indicate the active state.
- undo()
- class hmo.HMO.Node(x, y, atom_type='C·')
A class representing an atom (node) in the molecular graph.
Each Node object stores information about its position in the molecular diagram, its chemical element type (e.g., C, N, O), and its π-charge (from Hückel analysis).
- Parameters:
canvas (tk.Canvas) – The canvas on which the node (atom) will be drawn.
x (int) – The x-coordinate of the node in the canvas (in pixels).
y (int) – The y-coordinate of the node in the canvas (in pixels).
radius (int, optional) – Radius of the circle representing the atom (default is 20 pixels).
atom_type (str, optional) – Chemical element symbol for the node (default is ‘C’).
color (str, optional) – Fill color for the node (default is ‘white’).
- x
X-coordinate of the node center.
- Type:
int
- y
Y-coordinate of the node center.
- Type:
int
- radius
Radius of the circle representing the atom.
- Type:
int
- atom_type
Chemical element symbol (e.g., ‘C’, ‘N’, ‘O’).
- Type:
str
- color
Fill color of the atom.
- Type:
str
- circle
ID of the oval shape on the canvas (for drawing reference).
- Type:
int
- label
ID of the text label on the canvas (for element symbol).
- Type:
int
- pi_charge
The π-electron charge on the atom, computed after Hückel analysis.
- Type:
float or None
- draw()
Draws the node (circle + label) on the canvas.
- update_label()
Updates the displayed label based on the atom type and charge.
- is_within(x, y)
Checks if a given (x, y) coordinate is within the node’s radius.
- move_to(new_x, new_y)
Moves the node to a new position on the canvas.
- set_pi_charge(charge)
Sets the π-charge for the atom and updates the label accordingly.
- class hmo.HMO.ToolTip(widget, text='widget info')
This class attaches a tooltip (a small pop-up window displaying text) to any Tkinter widget. The tooltip appears when the mouse hovers over the widget and disappears when the mouse leaves.
The tooltip text is rendered using a custom Open Sans Regular font loaded from a TrueType Font (TTF) file located at ‘Fonts/OpenSans/static/OpenSans-Regular.ttf’. This ensures a consistent and modern look across different platforms and display environments.
- Parameters:
widget (tk.Widget) – The Tkinter widget to which the tooltip will be attached.
text (str) – The text content to display in the tooltip.
- widget
The widget associated with the tooltip.
- Type:
tk.Widget
- text
The message displayed when hovering over the widget.
- Type:
str
- tooltip_window
The pop-up window that displays the tooltip text (created when the mouse enters the widget).
- Type:
tk.Toplevel or None
- OpenSansReg_font
The custom font object used to render the tooltip text, loaded from OpenSans-Regular.ttf.
- Type:
tkFont.Font
- Main Methods
- -------
- show_tooltip(event=None)
Creates and displays the tooltip near the mouse cursor using the Open Sans font.
- hide_tooltip(event=None)
Destroys the tooltip window when the mouse leaves the widget.
- enter(event=None)
- hidetip()
- leave(event=None)
- motion(event=None)
- schedule()
- showtip(event=None)
- unschedule()
- hmo.HMO.compute_mean_bond_length(df_atoms, df_bonds)
Compute the average bond length in grid units based on atom coordinates.
- Parameters:
df_atoms (pd.DataFrame) – Must contain ‘Atom’, ‘X (grid units)’, ‘Y (grid units)’ columns.
df_bonds (pd.DataFrame) – Must contain ‘Atom 1’ and ‘Atom 2’ columns.
- Returns:
Average bond length.
- Return type:
float
- hmo.HMO.draw_mo_on_ax_dual_lobes(df_MOs, df_atoms, df_bonds, idx, ax, scale_lobe_factor, max_coef_global, size, energies=None, occupations=None, lobe_offset=0.1)
Draw a molecular orbital with back and front lobes on a matplotlib Axes.
- Parameters:
df_MOs (pd.DataFrame) – Molecular orbital coefficients (atoms × orbitals).
df_atoms (pd.DataFrame) – Atom coordinates and labels.
df_bonds (pd.DataFrame) – Bond connections between atoms.
idx (int) – Index of the molecular orbital to draw.
ax (matplotlib.axes.Axes) – Axes to draw on.
scale_lobe_factor (float) – Scaling factor applied to each coefficient to compute lobe radius.
size (dimension of each MO box)
energies (list of str, optional) – Formatted energy labels (e.g., ‘α + 1.00β’).
occupations (list of int, optional) – Electron counts per MO (e.g., 2e, 0e).
lobe_offset (float, default=0.5) – Offset for visual 3D effect (in grid units).
- hmo.HMO.extract_energies_and_occupations_from_columns(columns)
Extracts energy expressions and occupation numbers from MO column headers.
- Parameters:
columns (list of str) – Column names from the MO coefficient DataFrame.
- Returns:
energies (list of str) – Formatted strings like ‘α + 1.20β’.
occupations (list of int) – Electron count (0, 1, or 2) per MO.
- hmo.HMO.extract_energy_groups(df_MOs)
Extract energy values and group orbital indices by energy.
- Parameters:
df_MOs (pd.DataFrame) – DataFrame with column names like ‘E = α + 1.00βn2e’
- Returns:
energy_groups – Dictionary mapping energy (float) to list of MO indices.
- Return type:
dict[float, list[int]]
- hmo.HMO.lighten_color(color, amount=0.5)
- hmo.HMO.lobes_sizes(df_MOs, mean_bond_length=None, scale=None, factor=0.9, max_display_radius=None)
Compute the global lobe scaling factor based on the maximum MO coefficient.
This function supports two use cases: 1. If max_display_radius is provided, the largest lobe will have this radius in display units. 2. Otherwise, the lobe size will be scaled as a fraction (factor) of the half bond length (estimated as: factor × mean_bond_length × scale / 2).
- Parameters:
df_MOs (pd.DataFrame) – DataFrame of molecular orbital coefficients (rows: atoms, columns: MOs).
mean_bond_length (float, optional) – Average bond length in grid units (required if max_display_radius is not provided).
scale (float, optional) – Current display scale applied to coordinates (required if max_display_radius is not provided).
factor (float, default=0.90) – Maximum lobe radius as a fraction of half a bond length (only used if max_display_radius is None).
max_display_radius (float, optional) – Maximum allowed lobe radius in display units (used to keep lobes within frame limits, e.g., 2.0).
- Returns:
max_coef_global (float) – Maximum absolute coefficient found in the MO matrix.
scale_lobe_factor (float) – Multiplicative factor to convert each coefficient into a lobe radius.
- hmo.HMO.render_all_OMs_grid_with_dual_lobes(df_MOs, df_atoms, df_bonds, scale_lobe_factor, max_coef_global, energies=None, occupations=None, cell_size_cm=3, max_per_row=6, size=8)
Render a grid of molecular orbitals with consistent lobe scaling.
- Parameters:
df_MOs (-)
df_atoms (-)
df_bonds (-)
scale_lobe_factor (-) – Global scaling factor for lobe radii.
energies (-) – Energy labels for each MO.
occupations (-) – Occupation numbers for each MO.
cell_size_cm (-) – Width/height of each subplot in centimeters.
max_per_row (-) – Maximum number of MOs per row.
- Returns:
fig – The rendered figure.
- Return type:
matplotlib.figure.Figure
- hmo.HMO.render_double_panel_charges_bonds(nodes, bonds, charges, bond_orders, formal_charges)
Render two side-by-side panels representing molecular structure and bonding and charge descriptors.
The function generates a matplotlib figure of total size 26 cm (widthPlot_cm) × 13 cm (heightPlot_cm), composed of two panels: - Left panel: the sigma skeleton (σ) of the molecule, with indexed atoms and the number of pi electrons they bring to the pi system. - Right panel: bond orders and atomic charges, displayed on the same structure.
This visualization is suitable for publication or detailed analysis, with precise control over bond lengths and graphical scaling.
- Parameters:
nodes (list) – List of atomic nodes, each with .x and .y attributes and an atom_type (chemical element).
bonds (list of tuple) – List of (i, j) pairs indicating bonded atom indices.
charges (list of float) – List of computed atomic charges.
bond_orders (dict) – Dictionary mapping (i, j) pairs to bond order values (float).
formal_charges (list) – list of ChargeNode instances
- Returns:
fig – The matplotlib figure object containing the two rendered panels.
- Return type:
matplotlib.figure.Figure
- hmo.HMO.render_energy_diagram_matplotlib(energy_groups, occupations, descriptors=None, width_cm=5, height_cm=16)
- hmo.HMO.resource_path(relative_path)
Get absolute path to resource, works for dev and PyInstaller.
- hmo.HMO.save_figure_as_pdf(fig, filename)
Save a matplotlib figure as a PDF with exact dimensions and no automatic cropping.
- Parameters:
fig (matplotlib.figure.Figure) – The figure object to save.
filename (str) – Output file path, typically ending in .pdf
- class hmo.HMO.HMOViewerParameters
Visualization and layout parameters for the HMOViewer interface.
This class centralizes all GUI layout settings, dimensions, and rendering parameters used in the molecular orbital (MO) diagram viewer. It includes frame sizes and positions for HOMO/LUMO, diagram coordinates, canvas size, and parameters for drawing molecular orbitals (lobes, bonds).
- FRAME_WIDTH
Width (in pixels) of each MO visualization frame (for HOMO/LUMO).
- Type:
int
- FRAME_HEIGHT
Height (in pixels) of each MO visualization frame.
- Type:
int
- FRAME_LUMO_X
X-coordinate (in pixels) of the LUMO frame’s top-left corner.
- Type:
int
- FRAME_LUMO_Y
Y-coordinate (in pixels) of the LUMO frame’s top-left corner.
- Type:
int
- FRAME_HOMO_X
X-coordinate of the HOMO frame’s top-left corner (aligned with LUMO frame).
- Type:
int
- FRAME_HOMO_Y
Y-coordinate of the HOMO frame’s top-left corner (placed below LUMO with spacing).
- Type:
int
- BOTTOM_OF_HOMO
Y-coordinate of the bottom of the HOMO frame.
- Type:
int
- MARGIN_BOTTOM
Margin (in pixels) below the HOMO frame in the canvas.
- Type:
int
- CANVAS_HEIGHT
Total height (in pixels) of the drawing canvas, computed dynamically.
- Type:
int
- CANVAS_WIDTH
Total width (in pixels) of the drawing canvas.
- Type:
int
- DIAG_X
X-position (in pixels) for the center of the MO energy diagram (left side).
- Type:
int
- DIAG_Y_TOP
Top Y-coordinate of the MO energy diagram.
- Type:
int
- DIAG_Y_BOTTOM
Bottom Y-coordinate of the MO energy diagram.
- Type:
int
- DIAG_WIDTH_UNIT
Width of a unit interval in the diagram (used for scaling purposes).
- Type:
int
- SHRINK_FACTOR
Scaling factor applied to lobe sizes to prevent overlap.
- Type:
float
- LOBE_OFFSET
Pixel offset for lobe positioning when rendering orbitals.
- Type:
int
- TARGET_BOND_PX
Target length (in pixels) for bond drawings between atoms.
- Type:
int
Notes
The canvas is designed to hold both HOMO and LUMO visualizations side by side with appropriate margins.
The MO energy diagram is drawn to the left of the MO frames for visual reference.
The SHRINK_FACTOR and LOBE_OFFSET parameters allow fine control of orbital lobe rendering for clarity.
The Path2Imgs attribute should point to a valid directory containing any additional images used in the visualization (e.g., backgrounds, decorations).
Example
>>> HMOViewerParameters.FRAME_WIDTH 700
>>> HMOViewerParameters.Path2Imgs PosixPath('DesignMOdiagram')
- class hmo.HMO.HuckelParameters
Container for Huckel model parameters and visualization settings.
This class centralizes all constants and mappings used for building and analyzing molecules within the Hückel framework. It includes atomic and bond parameters, grid and drawing settings, and atom display options for the GUI.
- GRID_SIZE
The size of one grid unit (in pixels) for positioning atoms in the molecular canvas.
- Type:
int
- ATOM_RADIUS
The radius (in pixels) of the circle used to draw an atom on the canvas.
- Type:
int
- HIGHLIGHT_RADIUS
The radius (in pixels) of the highlight circle used when selecting atoms or bonds.
- Type:
int
- ATOM_COLORS
A dictionary mapping atom type strings (e.g., ‘C·’, ‘O:’, ‘N+·’) to their display color in hex code or standard color names.
- Type:
dict
- ATOM_OPTIONS
The list of atom types available for selection and drawing in the molecule builder.
- Type:
list of str
- Huckel_atomic_parameters
- A dictionary mapping atom types to their Hückel parameters, each of which is a dictionary with:
‘alpha_expr’: a string expression for the Coulomb integral α (often depends on β),
‘Fx’: the index of free valence (reactivity index) representing the reactivity of the center,
‘n_pi’: the number of π-electrons contributed by the atom.
- Type:
dict
- Huckel_kXY_parameters
A nested dictionary mapping pairs of atom types to their interaction energies (float), representing the interaction between two 2p atomic orbitals (used for the β term in the Hückel matrix).
- Type:
dict
Notes
The atom types include common π-conjugated atoms and heteroatoms (e.g., C·, N·, N:, O·, etc.).
The ▯ symbol (e.g., ‘B▯’) indicates that the atom holds a π-vacancy (e.g., boron with an empty p-orbital).
A colon (:) after the atom type (e.g., ‘O:’, ‘N:’) denotes that the atom provides a lone pair into the π system (typically 2 π-electrons).
A dot (·) after the atom type (e.g., ‘C·’, ‘O·’, ‘N·’) indicates the atom provides a single π-electron to the system.
The ‘Fx’ parameter (index of free valence) represents the theoretical reactivity of the atom in the π system and can be used as a qualitative indicator of chemical reactivity.
The Huckel_kXY_parameters dictionary does not hold mere bond scaling factors, but rather contains interaction energies between two 2p atomic orbitals, which define the off-diagonal β terms in the Hückel Hamiltonian.
The alpha_expr parameter (Coulomb integral) gives the energy of an electron in a 2p atomic orbital of a given atom.
- Typically, α and β are negative values. For carbon atoms, it is common to use:
α_C ≈ -11.0 eV (Coulomb integral / 2p orbital energy),
β_CC ≈ -2.7 eV (interaction between two carbon 2p orbitals).
For heteroatoms (atoms other than carbon), the parameters α_X and β_XY are expressed as functions of α_C and β_C, enabling a transferability of parameters while keeping carbon as the reference.
Example
>>> # Access a color for carbon >>> HuckelParameters.ATOM_COLORS['C·'] '#909090'
>>> # Access π-electron count for nitrogen (lone pair donor) >>> HuckelParameters.Huckel_atomic_parameters['N:']['n_pi'] 2
>>> # Access 2p–2p interaction energy between C and O >>> HuckelParameters.Huckel_kXY_parameters['C·']['O·'] 1.06
Contents: