Skip to main content

GLOMOS

GLobal Optimization of MOlecular Systems — a genetic algorithm for the global optimization of atomic clusters and molecules, built on top of AEGON.

GLOMOS orchestrates the genetic algorithm (initial population, crossover, mutation, structural deduplication, stop criteria) and delegates every energy evaluation and local optimization to AEGON's calculator registry. GLOMOS itself never talks to a quantum chemistry code or a potential directly — it only calls aegon.calculators.build(calc_type, **kwargs), so any calculator AEGON supports is automatically available to the genetic algorithm. The GA operators themselves (crossover, mutation, and parent selection) live in glomos.generation, not AEGON — AEGON only supplies the random/symmetry-constrained structure generators, geometry utilities, and USR discrimination they're built on. Parent selection has two independent implementations: fitness-proportional roulette wheel (the conventional GEGA driver) and structural clustering (the GCLUS driver, which replaces fitness entirely with MBTR-descriptor/Ward clustering) — see Genetic algorithm search and Clustering-based genetic algorithm search.


Table of Contents


Features

  • Four search drivers — heuristic_kick.py (staged local-opt + discrimination, no evolutionary operators), heuristic_ga.py (roulette-wheel GA over clusters, "GEGA"), heuristic_clustering.py (structural-clustering GA over clusters, "GCLUS" — same operators as GEGA, but parent selection replaces fitness with MBTR/Ward clustering), heuristic_ga_rotamers.py (GA over dihedral angles for conformer search, "RTMR").
  • Own GA operators (glomos.generation) — cluster crossover/mutation (generation/cluster_crossover.py/cluster_mutant.py, shared by GEGA and GCLUS — GCLUS additionally supports two children per crossover pair and chained multi-operator mutants), rotamer crossover/mutation (generation/rotamer_crossover.py/rotamer_mutant.py), fitness-proportional roulette selection and structural-clustering selection (both in generation/selection.py), and random-individual insertion (generation/cluster_random.py's popgen_randoms, backing nof_randoms below) all live in GLOMOS itself, not AEGON — AEGON only supplies the random/symmetry-constrained structure generators, geometry utilities, and USR discrimination they're built on.
  • Shared driver helpers (glomos.libshared) — calculator dispatch (dispatch_calculator, used by all four drivers including RTMR), retry-on-non-convergence (optimize_with_retries, GEGA/GCLUS/KICK), and INPUT-value/site-config resolution (resolve_optional) are factored out once and reused instead of being duplicated per file.
  • Calculator-agnostic — every driver dispatches through AEGON's registry: LJ, Sutton-Chen, TiO2, EMT, ANI, Gaussian, ORCA, MOPAC, GULP, VASP, selected by a single calculator key.
  • Unit-consistent — one units key (eV/atomic/kcal) fixes energy and force together across every calculator.
  • Plain-text input files — INPUT_GLOMOS_<CALCULATOR>_<ALGORITHM>_<SYSTEM>.txt (GEGA/GCLUS/KICK/RTMR), same convention as solids/examples.

Installation

pip install glomos

Requires Python >= 3.10. GLOMOS depends on AEGON with the [ani] extra (installs torch/torchani for the ANI calculator); no separate installation step is needed.


Dependencies

Package Role
aegon [ani] Structure generation, unit conversion, and the calculator registry (LJ, SC, TiO2, EMT, ANI, Gaussian, ORCA, MOPAC, GULP, VASP)
growpal MBTR descriptors and Ward agglomerative clustering (libdescriptors/libclustering), used by the GCLUS driver's structural-clustering parent selection

All other dependencies (ASE, NumPy, SciPy, Numba, Pydantic, PyYAML, joblib, torch, torchani) come transitively through aegon[ani]; dscribe, molsympy, and scikit-learn come transitively through growpal.


The INPUT file

GLOMOS reads a plain-text input file with a composition block and key-value parameters (parsed by aegon.io.stdio.read_main_input):

---COMPOSITION---
H  4
O  2
---COMPOSITION---

#EVOLUTIVE PARAMETERS:
nof_initpop             4    #Initial Population
nof_matings             2    #Number of matings
nof_mutants             2    #Number of mutants
nof_randoms             2    #Insertion of new individuals

#ENERGY UNITS: eV | atomic (Eh) | kcal (kcal/mol)
units                   kcal   #sets energy AND force units together

#DISCRIMINATION PARAMETERS:
tol_similarity          0.96
tol_energy              0.10
cutoff_energy           10.0
cutoff_population       10

#STOP CRITERION:
nof_generations         10
nof_repeats             3
nof_stagnant            5

#THEORY LEVEL:
calculator              GAUSSIAN
nof_processes           4

#OUTPUT FILE:
initial_file            initial.xyz
output_file             summary.xyz

Calculator-specific keys (metal_symbol for SC, ani_model for ANI, vasp_potcar/vasp_latsp for VASP, the ---GAUSSIAN---/---ORCA---/ ---MOPAC---/---GULP---/---VASP--- route blocks) apply only to the calculator selected. Binary paths and scratch folders normally come from AEGON's site configuration (python -m aegon.config show), not from this file — an INPUT-level override (orca_path/orca_mpi_path/orca_mpi_libs for ORCA, g16root for GAUSSIAN, mopac_path, gulp_path, vasp_exe/ vasp_mpirun for VASP, ...) still wins over the site config when present.

For ORCA specifically, none of orca_path/orca_mpi_path/orca_mpi_libs need to be set anywhere (INPUT file or site config): when left unset, the orca binary is resolved from the job's own PATH instead, so a Slurm script that does module load orca/<version> before running the driver is enough on its own — the INPUT file only needs calculator ORCA and the ---ORCA<n>--- block(s). Set orca_path explicitly only to pin a specific build not exposed via modules.

Every run prints a warning for any key or block present in the INPUT file but never actually read by the algorithm/calculator combination selected — e.g. a typo, a key that only applies to a different calculator, or a stop-criterion key from KICK left over after switching an INPUT file to GEGA. Silent otherwise.

Boolean keys (discriminate, rename, disc_unconnected_opt for KICK; matings, mutants, two_childs, two_mutations for GCLUS) accept only True/False (case-insensitive) via read_main_input.get_bool — deliberately not a grab-bag of alternate spellings (no yes/no, 1/0, on/off).


Supported calculators

calculator Backend Native units KICK GEGA GCLUS RTMR Notes
LJ aegon.optimization.potentials.lj eV ✅ ✅ ✅ — Generic Lennard-Jones, no external binary
SC aegon.optimization.potentials.sc eV ✅ ✅ ✅ — Sutton-Chen; requires metal_symbol
TIO2 aegon.optimization.potentials.tio2 eV ✅ ✅ ✅ — Buckingham + Coulomb + LJ for TiO2
EMT aegon.optimization.potentials.emt eV ✅ ✅ ✅ — ASE Effective Medium Theory; Al, Ni, Cu, Pd, Ag, Pt, Au
ANI aegon.optimization.potentials.ani kcal/mol ✅ ✅ ✅ ✅ Machine-learned potential (ANI1x/ANI1ccx/ANI2x); requires aegon[ani]
GAUSSIAN Gaussian 16 kcal/mol ✅ ✅ ✅ ✅ External binary
ORCA ORCA kcal/mol ✅ ✅ ✅ ✅ External binary
MOPAC MOPAC kcal/mol ✅ ✅ ✅ ✅ External binary
GULP GULP eV ✅ ✅ ✅ — External binary; periodic and cluster-in-vacuum-box
VASP VASP kcal/mol ✅ ✅ ✅ — External binary; periodic, requires POTCAR

GCLUS dispatches through the identical dispatch_calculator() (from glomos.libshared) used by GEGA and KICK (all 10 calculators). RTMR is limited to ANI/GAUSSIAN/ORCA/MOPAC — the rest have no organic-molecule parameterization or are otherwise not the tool for a conformer search. GCLUS itself has no molecular-graph/bonding constraint (see its own section below), so unlike RTMR it can technically run any composition through any of the 10 calculators, including organic compositions — that combination builds raw atomic arrangements, not chemically-sensible conformers.


heuristic_kick.py: a population goes through number_of_stages local-opt + discrimination passes, no crossover/mutation. Template-driven engines (Gaussian, ORCA, MOPAC, GULP, VASP) take one input block per stage (---GULP1---/---GULP2---, ---INCAR1---/---KPOINTS1--- for VASP), so stages can run at different levels of theory.

from glomos.heuristic_kick import stochastic_kick

population = stochastic_kick('INPUT_GLOMOS_LJ_KICK_Mo8.txt')

Examples: x_run_glomos_{lj,sc,tio2,emt}_kick_{mo8,cu8,tio2,au8}.py, ..._gulp_kick_cu8.py, ..._{ani,orca,gaussian,vasp}_kick_h2o.py (seeded from the matching GEGA run's summary.xyz), ..._mopac_kick_si5o6.py (MNDO, self-generated population — see Genetic algorithm search), and ..._gaussian_kick_b10.py (multi-stage boron refinement).


heuristic_ga.py: roulette-wheel crossover/mutation, energy-cutoff + USR deduplication, stop on max generations / repeated isomers / stagnant cycles.

from glomos.heuristic_ga import genetic_algorithm

population = genetic_algorithm('INPUT_GLOMOS_GAUSSIAN_GEGA_H2O.txt')
for mol in population[:5]:
    print(mol.info['i'], mol.info['e'], mol.info['c'])

Population is written to output_file after every generation. Examples: x_run_glomos_{lj,sc,tio2,emt}_gega_{mo8,cu8,tio2,au8}.py, ..._gulp_gega_cu8.py, ..._{ani,orca,gaussian,vasp}_gega_h2o.py, ..._mopac_gega_si5o10.py (MNDO).

nof_opt_attempts (default 1, same key and semantics as KICK above) retries any structure whose info['c'] isn't 1 — i.e. the calculator's job didn't reach a real stationary point — from its current geometry, up to that many total attempts, before it's allowed into fitness-proportional selection. Applies to both the initial population and every generation's crossovers/ mutants, and works the same way for every calculator in the registry (not just the external QM codes): info['c'] is set uniformly by every *CalculatorStrategy.optimize_parallel(), so the retry loop only depends on that, never on which calculator produced it.

nof_randoms (default 0) inserts that many brand-new random individuals into every generation, alongside the usual crossovers and mutants — a way to reintroduce diversity into a search that's converging too quickly around one basin. Candidates go through the same structural-redundancy check as crossover/mutation offspring before being accepted: USR similarity plus energy tolerance against the running batch itself, against every non-optimized structure proposed so far this run, and against every optimized structure already accepted, so a random insertion can't keep reintroducing a structure the search has already explored or converged to.

Running several searches in sequence

from glomos.heuristic_ga import genetic_algorithm

genetic_algorithm('INPUT_GLOMOS_LJ_GEGA_Mo8.txt')
genetic_algorithm('INPUT_GLOMOS_SC_GEGA_Cu8.txt')
genetic_algorithm('INPUT_GLOMOS_GAUSSIAN_GEGA_H2O.txt')

heuristic_clustering.py: structurally identical to heuristic_ga.py's GEGA driver — same calculator dispatch (dispatch_calculator(), all 10 registered calculators), same nof_opt_attempts retry-on-non-convergence and nof_randoms random-insertion, same stop criteria — but replaces fitness-proportional roulette selection with glomos.generation.selection.Descriptor_and_clustering(): every generation, the current population is grouped into nof_groups structural clusters (MBTR descriptor + Ward agglomerative clustering, delegated to growpal.libclustering/growpal.libdescriptors — the same machinery GrowPAL uses to pick diverse candidates after a growth step) and the lowest-energy representative of each cluster becomes a "possible father" for crossover and mutation.

from glomos.heuristic_clustering import genetic_algorithm

population = genetic_algorithm('INPUT_GLOMOS_LJ_GCLUS_Mo20.txt')

GCLUS replaces GEGA's nof_matings/nof_mutants (target counts) with:

  • nof_groups — number of structural clusters (and therefore "possible fathers") per generation.
  • matings / mutants (True/False) — whether to run crossover/mutation at all. When matings is on, every pairwise combination of possible fathers is crossed (not a fixed target count), so offspring count depends on how many pairs survive discrimination.
  • two_childs (True/False) — keep both children a single Deaven-Ho cut produces (the complementary fragment pairing), not just one.
  • two_mutations (True/False) — chain two mutation operators per mutant instead of one (make_mutant(..., n_mutations=2)).

Examples: x_run_glomos_{lj,sc,tio2,emt}_gclus_{mo8,cu8,tio2,au8}.py (plus ..._lj_gclus_mo20.py, a second LJ size), ..._gulp_gclus_cu8.py, ..._{ani,orca,gaussian,vasp}_gclus_h2o.py, ..._mopac_gclus_si5o10.py.


heuristic_ga_rotamers.py: a GA over dihedral angles of a single molecule. Rotatable bonds are identified from the molecular graph of a rotamer_seed XYZ file; no COMPOSITION block.

from glomos.heuristic_ga_rotamers import conformational

population = conformational('INPUT_ROTAMERS.txt')

calculator is ANI (ani_model selects ANI1x/ANI1ccx/ANI2x), MOPAC, GAUSSIAN, or ORCA.

  • examples/INPUT_GLOMOS_MOPAC_RTMR_C8H9NO2.txt / ..._ANI_RTMR_C8H9NO2.txt — paracetamol, ANI1ccx.
  • examples/INPUT_GLOMOS_GAUSSIAN_RTMR_C2H6O.txt / ..._ORCA_RTMR_C2H6O.txt — ethanol, PBE0/Def2SVP.

Citation

If you use GLOMOS in your research, please cite the associated manuscript (in preparation), and the AEGON backend it builds on:

López-Castro C., Ortiz-Chi F., Merino G. An Efficient Growth Pattern Algorithm (GrowPAL) for Cluster Structure Prediction. J. Chem. Theory Comput. 2024, 20, 4939–4948.


Authors

  • Aileen Garcia Cano — Facultad de Ingeniería, Universidad Autónoma de Yucatán, Mérida, México
  • Gabriel Merino — Departamento de Física Aplicada, Cinvestav-IPN, Mérida, México
  • Filiberto Ortiz-Chi — Secihti-Departamento de Física Aplicada, Cinvestav-IPN, Mérida, México

License

See LICENSE.

Metadata

Release files for glomos 0.3.6

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for glomos 0.3.6
File Size Uploaded
glomos-0.3.6.tar.gz 45.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for glomos 0.3.6
File Interpreter ABI Platform
glomos-0.3.6-py3-none-any.whl Python 3 none any Details

Total release size: 88.6 kB

Release files / glomos-0.3.6.tar.gz

Download URL glomos-0.3.6.tar.gz
Size 45.2 kB
Tags Source
SHA-256 checksum
How to use checksums
3b1221dc404a9fb0d375c71f204b0941073e3e296aee229c6699eab0834fcc1d
BLAKE2b-256 checksum
How to use checksums
132436efe45e88c7643a3e705975e28e8b82bbd3ef4d7815620975e224fe6e91
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.6

Release files / glomos-0.3.6-py3-none-any.whl

Download URL glomos-0.3.6-py3-none-any.whl
Size 43.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
3d5830f9465f7713a30b2a2d79ae76a458fcb7d45c846c5d2595ce28c678879a
BLAKE2b-256 checksum
How to use checksums
b926517f8816bb3b849504cea4a492a0f9f395039e01296daaf52c451ed31d9a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.6

Release history Release notifications | RSS feed

This release

0.3.6 This release

2 release files

0.3.5

2 release files

0.3.4

2 release files

0.3.3

2 release files

0.3.2

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.9

2 release files

0.1.8

2 release files

0.1.7

2 release files

0.1.6

2 release files

0.1.5

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

0.0.9

2 release files

0.0.8

2 release files

0.0.7

2 release files

0.0.6

2 release files

0.0.5

2 release files

0.0.4

2 release files

0.0.3

2 release files

0.0.2

2 release files

0.0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page