normal_mode_sampling_step package#

Submodules#

normal_mode_sampling_step.metadata module#

This file contains metadata describing the results from NormalModeSampling

normal_mode_sampling_step.metadata.metadata = {'results': {'frequencies': {'description': 'The vibrational frequencies used for sampling', 'dimensionality': '[n_vibrational_modes]', 'type': 'float', 'units': 'cm^-1'}, 'maximum harmonic energy': {'description': 'Largest harmonic energy above the reference among the accepted samples', 'dimensionality': 'scalar', 'format': '.3f', 'type': 'float', 'units': 'kJ/mol'}, 'mean harmonic energy': {'description': 'Mean harmonic energy of the sampled ensemble, above the reference', 'dimensionality': 'scalar', 'format': '.3f', 'type': 'float', 'units': 'kJ/mol'}, 'number of imaginary modes': {'description': 'Number of imaginary-frequency modes found (0 for a minimum, 1 for a transition state); these are reported but not sampled', 'dimensionality': 'scalar', 'type': 'integer'}, 'number of low modes': {'description': 'Number of translational, rotational, and near-zero modes projected out before sampling', 'dimensionality': 'scalar', 'type': 'integer'}, 'number of rejected samples': {'description': 'Number of draws rejected by the energy ceiling and redrawn', 'dimensionality': 'scalar', 'type': 'integer'}, 'number of sampled modes': {'description': 'Number of modes actually displaced along', 'dimensionality': 'scalar', 'type': 'integer'}, 'number of samples': {'description': 'Number of sampled configurations generated', 'dimensionality': 'scalar', 'type': 'integer'}, 'number of vibrational modes': {'description': 'Number of real vibrational modes available to sample', 'dimensionality': 'scalar', 'type': 'integer'}, 'zero point energy': {'description': 'The harmonic zero-point vibrational energy', 'dimensionality': 'scalar', 'format': '.3f', 'property': 'zero point energy#NormalModeSampling#{model}', 'type': 'float', 'units': 'kJ/mol'}}}#

Properties that Normal Mode Sampling produces.

metadata[“results”] describes the results that this step can produce. It is a dictionary where the keys are the internal names of the results within this step, and the values are a dictionary describing the result. See the SEAMM developer documentation (or e.g. the Thermochemistry step) for the full field reference.

Normal Mode Sampling does not carry a computational model or keywords of its own – the energy/Hessian come from the Model Chemistry published upstream – so only results is populated here. The storable scalar (the zero-point energy) is defined in data/properties.csv; {model} is filled from the model chemistry at run time. The frequencies are exposed as a retrievable result (to a variable or table) but not stored as a per-configuration property.

normal_mode_sampling_step.normal_mode_sampling module#

Non-graphical part of the Normal Mode Sampling step in a SEAMM flowchart

The step draws an ensemble of displaced geometries by Wigner (or classical / ground-state) normal-mode sampling of the Hessian, and writes them as configurations of a new system for downstream single-point labelling.

The Hessian is obtained from the Model Chemistry published upstream (the _model_chemistry workspace variable), driven over MDI by seamm_mdi:

  • if the engine advertises the custom <HESSIAN command (MDIEngine.supports("<HESSIAN") – true only when it has a genuine analytic Hessian for the method), the analytic Hessian is used directly;

  • otherwise the Hessian is built by central finite differences of the forces (<FORCES) over the warm engine – cheap because the engine stays resident, and code-agnostic.

The physics helpers (normal_mode_analysis, sample_normal_modes, zero_point_energy) are module-level and free of any flowchart state so they can be unit-tested directly.

class normal_mode_sampling_step.normal_mode_sampling.NormalModeSampling(flowchart=None, title='Normal Mode Sampling', extension=None, logger=<Logger normal_mode_sampling_step.normal_mode_sampling (WARNING)>)[source]#

Bases: Node

The non-graphical part of a Normal Mode Sampling step in a flowchart.

analyze(P=None, data=None, out_name='', n_refs=1, indent='', **kwargs)[source]#

Summarize what was generated to the step’s output.

description_text(P=None)[source]#

Create the text description of what this step will do.

property git_revision#

The git version of this module.

run()[source]#

Run a Normal Mode Sampling step.

property version#

The semantic version of this module.

normal_mode_sampling_step.normal_mode_sampling.normal_mode_analysis(hessian_au, masses_amu, coords_ang)[source]#

Diagonalize the (projected, mass-weighted) Hessian.

Parameters:
  • hessian_au ((3N, 3N) array) – The Cartesian Hessian in atomic units (hartree / bohr^2).

  • masses_amu ((N,) array) – Atomic masses in amu.

  • coords_ang ((N, 3) array) – Reference coordinates in Angstrom (for the rotation projection).

Returns:

  • frequencies_cm ((3N,) ndarray) – Frequencies in cm^-1, ascending, signed (negative == imaginary).

  • modes_mw ((3N, 3N) ndarray) – The corresponding orthonormal mass-weighted eigenvectors, as columns in the same order as frequencies_cm.

normal_mode_sampling_step.normal_mode_sampling.sample_normal_modes(frequencies_cm, modes_mw, masses_amu, n_samples, *, distribution='wigner', temperature=300.0, amplitude_cap=None, energy_ceiling=None, rng=None, max_tries_factor=100)[source]#

Draw displaced geometries by normal-mode sampling.

Parameters:
  • frequencies_cm ((M,) array) – Frequencies (cm^-1, positive) of the modes to sample.

  • modes_mw ((3N, M) array) – The matching orthonormal mass-weighted eigenvectors, as columns.

  • masses_amu ((N,) array) – Atomic masses (amu).

  • n_samples (int) – Number of accepted geometries to return.

  • distribution ({"wigner", "classical", "ground"})

  • temperature (float) – Temperature (K); ignored for the ground-state distribution.

  • amplitude_cap (float or None) – Clamp each normal-coordinate draw to this many standard deviations.

  • energy_ceiling (float or None) – Reject (and redraw) samples whose harmonic energy above the reference (kJ/mol) exceeds this.

  • rng (numpy.random.Generator or None)

  • max_tries_factor (int) – Safety bound on redraws (per requested sample) before giving up.

Returns:

  • displacements (list[(N, 3) ndarray]) – Cartesian displacements (Angstrom) to add to the reference geometry.

  • energies_kJ (list[float]) – Harmonic energy of each accepted sample above the reference (kJ/mol).

  • q_vectors (list[(M,) ndarray]) – The normal-coordinate displacement per sampled mode for each accepted sample, in amu^1/2 Angstrom (same mode order as frequencies_cm).

  • n_rejected (int) – Number of draws rejected by the energy ceiling.

normal_mode_sampling_step.normal_mode_sampling.zero_point_energy(frequencies_cm)[source]#

Harmonic zero-point energy (kJ/mol) from positive frequencies (cm^-1).

normal_mode_sampling_step.normal_mode_sampling_parameters module#

Control parameters for the Normal Mode Sampling step in a SEAMM flowchart

class normal_mode_sampling_step.normal_mode_sampling_parameters.NormalModeSamplingParameters(defaults={}, data=None)[source]#

Bases: Parameters

The control parameters for Normal Mode Sampling.

The keys are the parameters for this plug-in; each value is a dictionary describing that parameter (default, kind, units, enumeration, format, description, help). The Hessian is obtained at run time from the Model Chemistry published by an upstream Model Chemistry step (the _model_chemistry workspace variable) – there is deliberately no method/basis parameter here.

parameters{str: {str: str}}

A dictionary containing the parameters for the current step.

parameters = {'amplitude cap': {'default': 4.0, 'default_units': '', 'description': 'Amplitude cap (in sigma):', 'enumeration': ('none',), 'format_string': '.1f', 'help_text': "Clamp each normal-coordinate displacement to this many standard deviations, so no sample wanders toward dissociation. 'none' leaves the Gaussian tails uncapped.", 'kind': 'float'}, 'configuration name': {'default': 'sequential', 'default_units': '', 'description': 'Name the configurations:', 'enumeration': ('sequential', 'sample number', 'reference,sample'), 'format_string': '', 'help_text': "How to name each generated configuration. 'sequential' numbers them 1, 2, ... across all references; 'sample number' numbers them within each reference; 'reference,sample' labels them by reference and sample index (1,1  1,2  ...) so the samples of one reference group together. A comma (not '/') is used since '/' separates system and configuration names elsewhere.", 'kind': 'string'}, 'distribution': {'default': 'Wigner (quantum)', 'default_units': '', 'description': 'Amplitude distribution:', 'enumeration': ('Wigner (quantum)', 'classical (thermal)', 'ground state (0 K)'), 'format_string': '', 'help_text': "The distribution of normal-coordinate displacements. 'Wigner (quantum)' uses the quantum harmonic-oscillator width sigma^2 = (hbar/2 omega) coth(hbar omega / 2 kT), which captures the zero-point spread of stiff modes that classical sampling misses. 'classical (thermal)' uses the Boltzmann width sigma^2 = kT / omega^2. 'ground state (0 K)' is the Wigner distribution at T=0, i.e. pure zero-point motion.", 'kind': 'enum'}, 'energy ceiling': {'default': 'none', 'default_units': 'kJ/mol', 'description': 'Reject harmonic energy above:', 'enumeration': ('none',), 'format_string': '.1f', 'help_text': "Reject (and redraw) any sample whose harmonic energy above the reference exceeds this ceiling. 'none' accepts every draw.", 'kind': 'float'}, 'modes': {'default': 'all', 'default_units': '', 'description': 'Modes to sample:', 'enumeration': ('all',), 'format_string': '', 'help_text': "Which vibrational modes to displace along: 'all', or a list / range of 1-based mode indices ordered by increasing frequency (e.g. '1-3, 7'). Translational, rotational, and imaginary modes are always excluded, so a transition state is sampled along its real modes with the reaction coordinate left alone.", 'kind': 'string'}, 'number of samples': {'default': 20, 'default_units': '', 'description': 'Number of samples:', 'enumeration': (), 'format_string': '', 'help_text': 'How many displaced geometries to generate per reference structure.', 'kind': 'integer'}, 'random seed': {'default': 'random', 'default_units': '', 'description': 'Random seed:', 'enumeration': ('random',), 'format_string': '', 'help_text': "The seed for the random-number generator. Use 'random' for a fresh, non-reproducible seed, or an integer for a reproducible ensemble.", 'kind': 'string'}, 'results': {'default': {}, 'default_units': None, 'description': 'results', 'enumeration': (), 'format_string': '', 'help_text': 'The results to save to variables or in tables.', 'kind': 'dictionary'}, 'structure': {'default': 'current', 'default_units': '', 'description': 'Reference structure:', 'enumeration': ('current',), 'format_string': '', 'help_text': "The source of the reference structure(s) whose normal modes are sampled: 'current' for the current system, a system name, or a variable ($name) holding a list of configurations. The geometry should be a stationary point (a minimum, or a transition state) of the chosen Model Chemistry.", 'kind': 'string'}, 'structure configuration name': {'default': '', 'default_units': '', 'description': 'matching:', 'enumeration': (), 'format_string': '', 'help_text': "The configuration name or pattern, used with 'name is', 'name matches', or 'name regexp'.", 'kind': 'string'}, 'structure configurations': {'default': 'current', 'default_units': '', 'description': 'using configurations:', 'enumeration': ('current', 'all', 'last', 'first', 'name is', 'name matches', 'name regexp'), 'format_string': '', 'help_text': 'Which configuration(s) of the structure system to sample around. Each selected configuration is treated as an independent reference and gets its own set of samples. Ignored when the structure is a variable holding a list of configurations (all of them are used).', 'kind': 'string'}, 'system name': {'default': 'from structure', 'default_units': '', 'description': 'Name the sampled system:', 'enumeration': ('from structure',), 'format_string': '', 'help_text': "The name for the new system holding the sampled configurations. 'from structure' derives it from the reference system's name; otherwise the literal text is used.", 'kind': 'string'}, 'temperature': {'default': 300.0, 'default_units': 'K', 'description': 'Temperature:', 'enumeration': (), 'format_string': '.1f', 'help_text': "The temperature entering the amplitude distribution. Not used for the 'ground state (0 K)' distribution.", 'kind': 'float'}}#

normal_mode_sampling_step.normal_mode_sampling_step module#

class normal_mode_sampling_step.normal_mode_sampling_step.NormalModeSamplingStep(flowchart=None, gui=None)[source]#

Bases: object

Helper class needed for the stevedore integration.

This must provide a description() method that returns a dict containing a description of this node, and create_node() and create_tk_node() methods for creating the graphical and non-graphical nodes.

The dictionary for the description is the class variable just below these comments. The felds are as follows:

my_description{str, str}

A human-readable description of this step. It can be several lines long, and needs to be clear to non-expert users. It contains the following keys: description, group, name.

my_description[“description”]tuple

A description of the Normal Mode Sampling step. It must be clear to non-experts.

my_description[“group”]str

Which group in the menus to put this step. If the group does not exist it will be created. Common groups are “Building”, “Control”, “Custom”, “Data”, and “Simulations”.

my_description[“name”]str

The name of this step, to be displayed in the menus.

create_node(flowchart=None, **kwargs)[source]#

Create and return the new node object.

Parameters:
  • flowchart (seamm.Node) – A non-graphical SEAMM node

  • **kwargs (keyword arguments) – Various keyword arguments such as title, namespace or extension representing the title displayed in the flowchart, the namespace for the plugins of a subflowchart and the extension, respectively.

Return type:

NormalModeSampling

create_tk_node(canvas=None, **kwargs)[source]#

Create and return the graphical Tk node object.

Parameters:
  • canvas (tk.Canvas) – The Tk Canvas widget

  • **kwargs (keyword arguments) – Various keyword arguments such as tk_flowchart, node, x, y, w, h representing a graphical flowchart object, a non-graphical node for a step, and dimensions of the graphical node.

Return type:

TkNormalModeSampling

description()[source]#

Return a description of what this step does.

Returns:

description

Return type:

dict(str, str)

my_description = {'description': 'Sample the normal-mode space of a molecule from its Hessian (Wigner/thermal) to generate displaced structures', 'group': 'Building', 'name': 'Normal Mode Sampling'}#

normal_mode_sampling_step.tk_normal_mode_sampling module#

The graphical part of a Normal Mode Sampling step

class normal_mode_sampling_step.tk_normal_mode_sampling.TkNormalModeSampling(tk_flowchart=None, node=None, namespace='org.molssi.seamm.tk', canvas=None, x=None, y=None, w=200, h=50)[source]#

Bases: TkNode

The graphical part of a Normal Mode Sampling step in a flowchart.

See also

NormalModeSampling, NormalModeSamplingParameters

create_dialog()[source]#

Create the dialog for the Normal Mode Sampling parameters.

reset_dialog(widget=None)[source]#

Lay out the parameters frame in the Parameters tab.

reset_parameters_frame()[source]#

Lay out the control parameters for the current choices.

right_click(event)[source]#

Handle a right-click: add the Edit… item.

Module contents#

normal_mode_sampling_step A SEAMM plug-in for Wigner/thermal normal-mode sampling of the Hessian, to generate displaced structures (e.g. for MLFF training sets).