DescriPytor

Molecular Feature Extraction GUI

M2 Extractor · Sterimol · Visualization
Input & Molecule
Configure the input file and molecule selection for feature extraction.
📂

Input File

Supports .ftr (Feather), .xyz, or directory path

Used as label in output DataFrames
0-based conformer index within the file
🔢

Atom Renumbering (optional)

ℹ️ Maps old atom indices to new ones before extraction. Format: old:new, old:new e.g. 1:5, 2:3, 3:2 (1-based).
🧩

Features to Extract

Sterimol Configuration
Define the bond axis and parameters for Sterimol (B1, B5, L) calculation.
ℹ️
Sterimol measures steric bulk along a substituent bond. B1 = minimum width  ·  B5 = maximum width  ·  L = length along bond axis. Specify atom indices as 1-based integers.
📍

Bond Axis — Base Atoms

Atom at the bond start (base of substituent)
Atom defining the bond direction (Y-axis)
Atom from which the bond originates (sets XZ plane)

For computing multiple Sterimol vectors in one call. Each line = (origin, direction, from_dir).
🔭

Radii & Sub-structure

CPK is the DescriPytor default; Bondi matches Verloop's original definition

Only include atoms connected to direction atom's sub-graph
Comma-separated 1-based indices to exclude from calculation
🔄

B1 Angular Scan Settings

ℹ️ B1 is found by rotating the perpendicular plane and finding the minimum-width tangent wall. Coarse scan: 18°→108° in 9° steps · Fine scan: ±9° around best angle in 1° steps.

👁️

Inline Visualization

Calls visualize_bool=True — displays end-on and side-view plots inline
Charges & Dipole
Configure atomic charge extraction and dipole moment parameters.

Atomic Charge Extraction

Comma-separated 1-based indices. Leave blank for all atoms.
Δ

Charge Difference (optional)

ℹ️ Computes charge differences between two atom sets (e.g. before/after bond). Uses get_charge_diff_df(diff_indices).
🧲

Dipole Moment

Reads dip_x, dip_y, dip_z, total_dipole from Gaussian output
Controls placement of dipole arrow in 3D viewer
〰️

Vibrational Modes

Returns DataFrame with Frequency and Amplitude columns

Adds cross_angle, para_angle columns from ring vibration analysis
3D Viewer Options
Configure the interactive Plotly 3D molecular viewer and overlay vectors.
🔬

plot_interactions — 3D Viewer

Color of bond lines in the 3D viewer

🎯

show_single_molecule — Interactive Dash

ℹ️ Launches a Dash app at localhost:8050 with click-detection for atom selection. Returned atom indices can be used as base atoms for Sterimol.
Calls show_single_molecule() — allows clicking atoms to retrieve indices
🔀

compare_molecules — Conformer Overlay

Calls compare_molecules() — color-coded overlay of multiple conformers

Comma-separated 0-based conformer indices
Steriplot Options
Configure the 2D Sterimol diagnostic plots: end-on (XZ) and side-view (YZ).
📊
Two complementary 2D views are available:
  • End-on view (XZ plane) — looking down the bond axis. Shows atom circles, B1 tangent wall, B5 vector.
  • Side view (YZ plane) — along the bond axis. Shows L extent, B5 arrow, loc_B5 indicator.
🎯

End-on View — XZ Plane (plot_b1_visualization)

Calls plot_b1_visualization()
100
Points per atom circle. Higher = smoother but slower.

Overlay elements

Colors


↔️

Side View — YZ Plane (plot_L_B5_plane)

Calls plot_L_B5_plane()
100

Overlay elements


📈

B1 Angular Scan Plot (get_b1s_list)

Calls get_b1s_list(plot_result=True) — shows B1 as a function of scan angle

scans parameter — number of full rotations
Feather Dataset
Load a directory of .feather files via the Molecules class, browse samples, and send any molecule straight to the 3D viewer.
📁

Step 1 — Point to your dataset directory

Directory containing .feather files, one per molecule.
Added to sys.path so imports resolve correctly.
ℹ️
Run the generated scan script once from your Python environment. It loads every .feather in the directory using Molecules, serialises each molecule's XYZ + metadata to a single molecules_dataset.json file, then load that JSON here — no Python needed after that.
📂

Step 2 — Load molecules_dataset.json

📊

Batch Steriplots

(requires gui_server.py)
80
⚠️ Select Origin, Direction, and From-Dir atoms in the Click-to-Select tab first, then come back here.
Click-to-Select Atoms
Load a molecule from the dataset picker below or paste XYZ manually, then click atoms to fill index fields.
Target field:
📂

From Dataset

No dataset loaded
📄

XYZ Data

🎨

Display

Current selections
B1 Origin
B1 Direction
B1 From-Direction
Drop Atoms
Charge Atoms
Dipole Origin
Custom
⚛️ Paste XYZ data and click Load Molecule
💡 Pick a Target field above, click atoms in the viewer, then hit Compute in the Features panel →
⚛️ Sterimol select atoms
Bond axis atoms
Origin not set
Direction not set
From-dir not set
Paste JSON result here
Load a molecule from the
Dataset tab or paste XYZ above
🔧 Feature Calculator 0 features
Geometry — instant, no Python needed
Select 2 atoms for distance (Å)

Python backend — requires gui_server.py
Not connected localhost:7432

Expression — combine saved features

Saved features
No features saved yet.
No selections yet. Load a molecule and click atoms.
Feature Set Extraction
Configure and run Molecules.get_molecules_features_set() across the loaded dataset. Each feature type is independent — enable only what you need.
ℹ️
Atom indices are 1-based. Format: pairs as 1-2, triplets as 1-2-3, multiple separated by spaces: 1-2 3-4. The dataset directory and root path are read from the Feather Dataset tab.
🔬

Reference Molecule

No dataset loaded
The smallest molecule in the dataset is shown here as a picking reference. Click ⊕ Pick on a feature below, then click atoms in the viewer to build the index string.
Click ⊕ Pick on any feature row, then click atoms in the viewer →
Load a dataset first
🧩

Feature Types

0 enabled
Ring vibrations vibration
Each pair defines opposite atoms across a ring
Stretching vibration
Bending vibration
NPA charges charge
Natural Population Analysis — space-separated 1-based indices
Dipole electrostatic
dip_x, dip_y, dip_z, total_dipole — extracted automatically
NBO charges charge
Charge diff charge
Sterimol steric
Bond angles geometry
Bond lengths geometry
⚙️

Parameters

Overridden by per-feature Sterimol radii if set
Flag feature pairs with |r| above this value
🎯

Scope — which molecules

All molecules in the dataset directory will be processed.
💾

Output

A timestamp is appended automatically when saved via server
Guide & Examples
A complete walkthrough of every feature in this GUI — from loading your first dataset to interpreting the feature matrix.
🚀

Quick Start — 4 steps to a feature matrix

1

Scan your feather files

Run the scan script once to create molecules_dataset.json from a directory of .feather files.

python scan_feathers.py \
  --dir /path/to/feathers \
  --out molecules_dataset.json
2

Load the dataset

Open the Feather Dataset tab. Paste the directory path, click Scan & Load, or drag the JSON into the drop zone.

The molecule browser appears with atom count, dipole, and charge availability for each entry.

3

Pick atom indices

Open the Feature Set tab. The smallest molecule loads automatically in the mini viewer.

Click ⊕ Pick on any feature row, then click atoms in the viewer to fill index fields.

4

Run & export

Start gui_server.py, then click ▶ Run via server. Results appear as a scrollable table. Use 💾 Download CSV to save.

💡
No Python server? Click ⚙ Generate Python code to get a ready-to-run script you can paste directly into a notebook or terminal. Everything except the server buttons works offline.
📂

Loading a Dataset

DescriPytor works with .feather files — one per molecule — produced by Gaussian log post-processing. The GUI reads them through a pre-built JSON scan file.

Scan script

# generate molecules_dataset.json alongside your feather files
# Run once; re-run whenever you add or remove files
python scan_feathers.py --dir /your/feather/dir --out molecules_dataset.json

Three ways to load

MethodWhereNotes
Scan & Load buttonDataset Directory fieldRuns scan automatically if gui_server.py is running
Load JSON fileFile picker buttonPick the pre-built molecules_dataset.json directly
Drag & dropDrop zone on Dataset tabDrop the JSON file onto the highlighted area

JSON format expected

[
  {
    "name":  "compound_001",
    "n_atoms": 32,
    "xyz":   "32\ncompound_001\nC  1.234  0.000 ...",
    "energy": -1234.5678,
    "has_dipole": true,
    "charge_types": ["nbo", "hirshfeld"]
  },
  ...
]
💡
The Feather Dataset tab shows atom count, energy, dipole flag, and charge availability as columns in the molecule browser. Use the filter dropdowns to narrow down molecules that have the data you need.
🔢

Atom Indices — Format Reference

⚠️
All indices are 1-based. The first atom in the XYZ block is atom 1. This matches the numbering shown in hover labels in the 3D viewer.
Group typeFormatExampleUsed by
Single atom N 3 or 3 5 7 9 NPA charges, NBO charges
Atom pair N-M 1-2 or 1-2 3-4 Ring vib, Stretching, Sterimol, Charge diff, Bond length
Atom triplet N-M-K 1-2-3 or 1-2-3 4-5-6 Bending, Bond angle
Multiple groups space-separated 1-2 3-4 7-8 Any feature — one group per space token

How to find atom indices

A

Hover in any 3D viewer — a tooltip shows #N elem (x, y, z). The N is the 1-based index.

B

Enable atom labels — toggle Atom labels in the 3D Viewer Options tab to show persistent index labels on every atom.

C

Use ⊕ Pick buttons in the Feature Set tab — click atoms directly on the mini viewer to fill index fields automatically.

🧩

Feature Types — Complete Reference

vibration Ring Vibrations

Identifies the ring-breathing / ring-deformation frequency by finding the IR-active mode whose displacement matches the given opposite-atom pair.

Input: pairs of atoms on opposite sides of each ring
8-11 9-12 — two rings, one pair each

Output columns: ring_8-11, ring_9-12 (frequency in cm⁻¹)

vibration Stretching Vibrations

Finds the bond-stretching mode for each atom pair by searching for the maximum IR intensity within a frequency window.

Input: bond pairs + optional frequency window (default 1400–3500 cm⁻¹)
1-2 3-4

Output columns: stretch_1-2, stretch_3-4 (cm⁻¹)

vibration Bending Vibrations

Extracts bending (scissoring / wagging) modes for three-atom motifs by matching displacement vectors to the given triplet.

Input: atom triplets + threshold (default 200 cm⁻¹)
1-2-3 4-5-6

Output columns: bend_1-2-3, bend_4-5-6 (cm⁻¹)

charge NPA Charges

Natural Population Analysis charges for specified atoms. Requires NBO output in the Gaussian log.

Input: atom indices (sub_atoms)
3 5 7 9

Output columns: per-atom NPA charge values

electrostatic Dipole Moment

Extracts the Gaussian dipole moment directly from the log file. No atom input required — enabled by toggling the switch.

Input: none (automatic)

Output columns: dip_x, dip_y, dip_z, total_dipole (Debye)

charge NBO Charges

Natural Bond Orbital charges for specified atoms. Supports nbo, hirshfeld, and cm5 charge types.

Input: atom indices
3 5 7 9

Output columns: per-atom NBO charge values

charge Charge Difference

Computes the charge difference between two atoms in each pair — useful for measuring polarisation across a bond.

Input: atom pairs (reference−comparison)
3-5 7-9

Output columns: charge_diff_3-5, charge_diff_7-9

steric Sterimol

Computes Verloop Sterimol steric parameters along the bond defined by each origin→direction pair. Uses van der Waals radii (CPK by default).

Input: bond pairs — origin atom then direction atom
1-2 or 1-2 3-4

Output columns: B1_1-2, B5_1-2, L_1-2, loc_B5_1-2, B1_B5_angle_1-2

geometry Bond Angles

Calculates the angle at the middle atom of each triplet from the XYZ coordinates.

Input: atom triplets (vertex is the middle atom)
1-2-3 — angle at atom 2

Output columns: Angle_1-2-3 (degrees)

geometry Bond Lengths

Calculates the Euclidean distance between each atom pair from the XYZ coordinates.

Input: atom pairs
1-2 3-4

Output columns: Length_1-2, Length_3-4 (Å)
⚠️
Isotropic block — when Include energy & polarizability is checked, the feature set also appends energy and polarizability tensor components (iso, aniso, xx, yy, zz) if available in the log file. These require a Polar keyword in the Gaussian input.
📐

Sterimol Parameters Explained

ParameterSymbolMeaning
Minimum widthB1Smallest transverse extent of the substituent — a measure of the narrowest dimension perpendicular to the bond axis
Maximum widthB5Largest transverse extent — the widest reach of the substituent in any direction perpendicular to the bond
LengthLExtent along the bond (origin → direction) axis, including the van der Waals radius of the terminal atom
B5 locationloc_B5Position along the L axis where the maximum width B5 is found
B1–B5 angleB1_B5_angleAngle (degrees) between the B1 and B5 vectors in the plane perpendicular to the bond — describes asymmetry of the substituent

The Sterimol tab (single molecule) shows these as a colour-coded bar. The Steriplot tab renders them as publication-quality plots: an end-on view (XZ plane, shows B1/B5 contours) and a side view (YZ plane, shows L and the B5 projection).

💡
base_atoms = [origin, direction, from_direction] — the third atom defines the plane for the B1 measurement. A good choice is a neighbour of the origin atom that is not the direction atom, so the plane is unambiguous.
🖱️

Atom Picking Walkthrough

The Feature Set tab embeds a 3D viewer showing the smallest molecule in your dataset. Picking from the smallest molecule is reliable because every other molecule in the set typically shares the same core numbering — you pick once, run for all.

1

Load a dataset — the mini viewer auto-populates when you switch to the Feature Set tab. The molecule name and atom count appear below the viewer. Click ↻ Reload to refresh after loading a new dataset.

2

Enable a feature and click its ⊕ Pick button. The button highlights and the active picking bar appears at the top of the Reference Molecule card, showing which feature is active and how many atoms are still needed.

3

Click atoms in the viewer. Each click adds an atom chip to the picking bar with its index and element. Atoms highlight in sequence colour (blue → green → yellow → …). Hover over any atom first to confirm its index from the tooltip.

4

When the group is complete (pair = 2 atoms, triplet = 3, single = 1), the formatted string is appended to the input field with a brief flash. The buffer resets automatically — keep clicking to add more groups to the same feature.

5

Use ⌫ Undo last to remove the most recent atom if you clicked the wrong one. Use ✕ Done (or click ⊕ Pick on a different feature row) to switch features.

6

Clicking an atom already in the buffer removes it (toggle behaviour). This lets you correct mistakes without pressing Undo.

💡
The ↙ From viewer selection buttons on some rows copy the current selection from the main 3D viewer (Atom Selector tab) rather than the mini viewer — useful if you have already explored a specific molecule there.
🧬

Feature Set Extraction — Full Workflow

Start gui_server.py in a terminal — python gui_server.py. The status dot in the sidebar turns green when connected. The server handles all Python computation.

Set dataset directory in the Feather Dataset tab. This path is read by the server to instantiate the Molecules object.

Enable feature types in the Feature Set tab. Use the toggle switches on each row. The N enabled badge updates as you toggle.

Fill index inputs using ⊕ Pick (mini viewer) or type directly. Frequency ranges, thresholds, and radii have sensible defaults — only override if needed.

Choose scopeAll loaded molecules processes everything in the directory; Dataset selection only processes only the molecules you have checked in the molecule browser.

Click ▶ Run via server. Progress shows in the status line. Extraction can take from a few seconds to several minutes depending on molecule count and which features are enabled.

Review results — stat chips show molecule count, feature count, correlated pairs, and NaN columns. The correlation card lists feature pairs above the threshold. The full matrix is scrollable below.

Export with 📋 Copy as TSV (paste into Excel / Sheets) or 💾 Download CSV to save locally. Enable Save CSV in the Output card to also write to disk alongside the feather files.

Equivalent Python code

import sys
sys.path.insert(0, r'/path/to/MolFeatures')
from data_extractor import Molecules

mols = Molecules(r'/path/to/feathers')

entry_widgets = {
    'sterimol':    '1-2',          # Sterimol for bond 1→2
    'bond_angle':  '1-2-3 4-5-6', # two angles
    'bond_length': '1-2',          # one bond length
    'charges':     '3 5 7',        # NBO charges on atoms 3, 5, 7
    'dipole':      '1',            # enable dipole (value ignored)
}
parameters = {'Radii': 'CPK', 'Isotropic': True}

df = mols.get_molecules_features_set(
    entry_widgets = entry_widgets,
    parameters    = parameters,
    save_as       = True,
    csv_file_name = 'my_features',
)
print(df)
📊

Interpreting Results

IndicatorMeaningWhat to do
NaN in a column That molecule lacked the data for this feature (missing NBO block, no frequency calculation, etc.) Check the original Gaussian log. Consider excluding that feature or those molecules from the model.
Correlated pair r ≥ 0.999 Nearly identical columns — likely two features that measure the same thing in this dataset Drop one of the pair before using the matrix in a regression or ML model.
Correlated pair 0.8 ≤ r < 0.999 Highly but not perfectly correlated — may still carry independent information Investigate the pair; use domain knowledge to decide which to keep.
Stat chip — features = 0 All feature extractions failed silently Check the terminal output of gui_server.py for error messages per molecule.
💡
Adjust the Correlation threshold slider (default 0.8) in the Parameters card before running to tune how aggressively correlated pairs are flagged.
⚠️
The feature matrix is sorted by molecule name (descending). If your molecule names encode a numeric ID (e.g. cpd_001, cpd_002), the sort will be numeric within the name pattern. Use the Save CSV option to persist the sorted order.
🔬

Single-Molecule Tools

Beyond the batch Feature Set, you can compute and visualise individual molecule properties from the Configuration and Visualization tabs.

ToolTabRequires serverDescription
Sterimol (single)SterimolYesCompute B1/B5/L for the currently loaded molecule. Results render as a colour bar in the Features panel.
Charges & DipoleCharges & DipoleYesRetrieve NBO/hirshfeld/cm5 charges and dipole components for selected atoms.
Steriplot (single)SteriplotYesServer-side matplotlib figure — end-on (XZ) and side (YZ) views of the Sterimol cone around the substituent.
Batch SteriplotSteriplotYesGenerate both steriplot views for all selected molecules and browse them in a card grid.
Geometry featuresFeature CalculatorNoDistance, angle, dihedral, centroid distance — computed client-side from XYZ, instant, no server needed.
Expression builderFeature CalculatorNoCombine named computed values into custom expressions (e.g. B5 / L) and save them to the feature registry.

Atom Selector tab — selection modes

ModeColourPurpose
OriginblueStarting atom for Sterimol / dipole / NPA — defines the bond origin
DirectiongreenAtom the bond points toward — defines the Sterimol axis
From-DiryellowThird atom needed to define the reference plane for B1
Drop atomsredAtoms excluded from the Sterimol calculation (e.g. leaving groups, spectators)
Charge atomspurpleAtoms whose NBO/NPA charges are retrieved

Tips & Common Pitfalls

💡
Consistent numbering across your dataset is the most important requirement. All molecules must have the same atom ordering for batch features to be meaningful. If not, use DescriPytor's renumbering tools before running.
💡
Start with one molecule in the single-molecule tabs to verify your atom indices and Sterimol axis before running the full batch Feature Set.
💡
Generated Python code (⚙ Generate Python code button) is always in sync with the current form state — use it to document your extraction parameters alongside the CSV output.
⚠️
Sterimol needs 3 atoms in the single-molecule tool (Origin, Direction, From-Dir) but only 2 atoms (origin-direction pair) in the Feature Set batch mode. The third atom is inferred from the molecular graph in batch mode.
⚠️
Vibration features require a freq=... job in Gaussian. If your log files were optimisation-only, ring/stretching/bending columns will be empty. Energy requires a single-point or opt; polarizability requires Polar.
⚠️
NPA vs NBO charges — NPA (Natural Population Analysis, key sub_atoms) and NBO (Natural Bond Orbital, key charges) are different charge schemes both requiring NBO analysis in Gaussian (pop=nbo). Hirshfeld and CM5 charges come from a Multiwfn post-processing step.
Generated Python Code
Code snippet based on your configuration above. Copy and run in your Python environment.
Python 3 · DescriPytor / data_extractor.py Ready
# Click "Generate Code" to produce a script from your configuration above.
Parameter Reference
Quick reference for all function signatures and key parameters.
⚛️

get_sterimol()

get_sterimol(base_atoms, radii='CPK', sub_structure=True, drop_atoms=None, visualize_bool=None, mode='all')
# Returns → pd.DataFrame with index [B1, B5, L, loc_B5, B1_B5_angle]
ParameterTypeDefaultDescription
base_atomslist[int]Atom indices: [origin, direction, from_direction] (1-based)
radiistr'CPK'Van der Waals radii set: 'CPK', 'bondi', 'Pyykko'
sub_structureboolTrueUse only atoms in sub-graph connected to direction atom
drop_atomslist[int] | NoneNoneAtom indices to exclude from calculation
visualize_boolbool | NoneNoneShow inline plots during calculation
modestr'all'Which parameters to compute: 'all', 'B1', 'B5', 'L'
📊

plot_b1_visualization()

plot_b1_visualization(rotated_plane, edited_coordinates_df,
                       sterimol_df=None, n_points=100,
                       title="XZ plane — End-on view")
# Returns → matplotlib.figure.Figure
ParameterTypeDefaultDescription
rotated_planenp.ndarrayTransformed atomic coordinates in XZ plane
edited_coordinates_dfpd.DataFrameCoordinates DataFrame with VdW radii column
sterimol_dfpd.DataFrame | NoneNoneSterimol results for vector overlays
n_pointsint100Number of points per atom circle
titlestr"XZ plane…"Figure title
↔️

plot_L_B5_plane()

plot_L_B5_plane(edited_coordinates_df, sterimol_df,
                n_points=100, title="YZ plane — Side view")
# Returns → matplotlib.figure.Figure
ParameterTypeDefaultDescription
edited_coordinates_dfpd.DataFrameCoordinates with radii and Y-transformed positions
sterimol_dfpd.DataFrameSterimol results (must include B5, L, loc_B5)
n_pointsint100Circle resolution
titlestr"YZ plane…"Figure title
📐

Sterimol Output Parameters

ParameterUnitsColorDescription
B1Å■ greenMinimum width — smallest cross-section perpendicular to bond axis
B5Å■ redMaximum width — largest VdW extent in the perpendicular plane
LÅ■ blueLength — extent along the substituent Y-axis
loc_B5ÅY-position of the atom contributing to B5
B1_B5_angle°3D angle between B1 plane normal and B5 vector

Charge Types

KeyFull NameDescription
'nbo'Natural Bond OrbitalNBO partial charges from Gaussian NBO analysis
'hirshfeld'Hirshfeld / CM5Stockholder charges based on promolecular density partitioning
'cm5'CM5Charge model 5 — corrected Hirshfeld charges
'all'All typesReturns all available charge types in one DataFrame