extract_clusters_step package¶
Submodules¶
extract_clusters_step.cluster_sampling module¶
Sampling of n-molecule clusters from a (periodic) configuration.
The pure functions here have no dependence on the SEAMM framework, only on
numpy/scipy and the duck-typed molsystem configuration passed in, so they
can be unit-tested directly and reused outside a flowchart.
The approach:
Find the molecules (by bonds) and build a molecular contact graph: molecule A is adjacent to B if any contact atom of A is within
cutoff(minimum image) of any contact atom of B.Sample n-mers as connected subgraphs of that graph by random frontier growth from a random seed molecule. Every member interacts with at least one other, and chains, rings and stars all occur – unlike nearest-neighbour selection, which only ever yields the most compact cluster.
Optionally stratify the accepted clusters to be flat in a spread coordinate (radius of gyration or largest centroid separation of the molecules), with bin edges taken as quantiles of a pilot sample, and optionally balance jointly over contact-graph topology (motif).
Emit each cluster as an unwrapped, centred, non-periodic configuration with the molecules intact, a unique name carrying provenance, and optional per-configuration properties.
- extract_clusters_step.cluster_sampling.accepts_topology(adj, order, motifs=None, coordination=None)[source]¶
Whether the cluster
orderpasses the motif and centre-coordination filters. Returns (accepted, motif, n_edges, degrees).
- extract_clusters_step.cluster_sampling.bond_index_pairs(configuration)[source]¶
The bonds of a configuration as 0-based atom-index pairs, with orders.
For a configuration without symmetry operators (the normal case, and every non-periodic one) the pairs come straight from the bond table, since
symmetry.bond_atomsis only populated for periodic configurations. For a symmetric crystal the symmetry-expanded list is used.- Returns:
pairsis a list of (i, j) index tuples;ordersthe matching list of bond orders, or None if it could not be matched up.- Return type:
(pairs, orders)
- extract_clusters_step.cluster_sampling.check_bonds(configuration)[source]¶
Raise if the configuration has no bonds but clearly consists of molecules.
Molecules are found from the bonds, so a configuration read from a format without connectivity (e.g. extended XYZ without bond perception) would be treated as one atom per molecule and the “clusters” would silently be groups of atoms. Configurations made only of noble-gas atoms or monatomic ions are allowed through.
- extract_clusters_step.cluster_sampling.classify_motif(n, n_edges, degrees)[source]¶
Name the topology of the induced contact graph of an n-mer.
Only n <= 4 get descriptive names; larger clusters are labelled by edge count so they can still be balanced on topology.
- Parameters:
n (int) – Number of molecules.
n_edges (int) – Number of contact edges within the cluster.
degrees ([int]) – The degree of each molecule within the cluster.
- Return type:
str
- extract_clusters_step.cluster_sampling.cluster_motif(adj, order)[source]¶
The motif label, edge count and degree list of the cluster
order.
- extract_clusters_step.cluster_sampling.cluster_summary(records, edges=None)[source]¶
Tabulate how a set of extracted n-mers is distributed over motif and spread bin – the quick check that the set is actually balanced.
- Parameters:
records ([dict]) – The records from
extract_nmers().edges ([float] or None) – The bin edges, printed as a final line if given.
- Return type:
str
- extract_clusters_step.cluster_sampling.extract_nmers(configuration, n, n_samples, *, cutoff=3.5, contact_elements=None, spread_metric='rg', spread_bins=None, balance_motifs=False, motifs=None, coordination=None, system=None, system_name='clusters', name_prefix='', max_attempts=None, rng=None, store_properties=True, seen=None)[source]¶
Extract n-molecule clusters from a (periodic) configuration.
The clusters are returned as unwrapped, non-periodic configurations suitable for cluster QM.
Selection is by connected subgraph of a molecular contact graph, not by nearest neighbours: every molecule in a returned n-mer is within
cutoffof at least one other, but chains, rings and stars all occur, and seeds are random so a single frame yields many distinct clusters.- Parameters:
configuration (molsystem _Configuration) – Source configuration (periodic or not). Molecules are found by bonds.
n (int) – Molecules per cluster (>= 2).
n_samples (int) – Target number of clusters (fewer if the pool or quotas run out).
cutoff (float) – Contact distance (Å) defining the neighbour graph. 3.5 with
contact_elements=["O"]is the usual H-bond criterion for water.contact_elements (list[str] or None) – Elements whose atoms define contact; None uses all atoms.
spread_metric ("rg" | "dmax") – Compactness coordinate used for stratification: radius of gyration of the molecular centroids, or the largest centroid-centroid distance.
spread_bins (int, sequence of float, or None) – Bin edges on the spread coordinate. An int asks for that many equal-quantile bins, with edges taken from an unstratified pilot sample of the same frame – the usual choice, since sensible edges depend on n and on the system. If given, acceptance is quota- limited so bins fill roughly evenly (flat-in-spread, analogous to the dimer builder’s flat-in-energy selection). Samples outside the edges are rejected. None disables stratification.
balance_motifs (bool) – Also balance across contact-graph topology (chain/ring/star/…), jointly with the spread bins.
motifs (iterable of str or None) – Accept only clusters whose contact-graph motif is one of these (see
motif_names()); None accepts every motif. Rejected candidates count against the attempt budget, so rare motifs (rings are a few percent of water trimers) may need a larger budget.coordination (iterable of int or None) – Accept only clusters whose most-connected molecule has one of these numbers of contacts within the cluster (its degree in the induced contact graph) – e.g.
[3]for star tetramers,[4]for a complete first shell. None accepts any. Stored on every cluster as thecentre coordinationproperty.system (molsystem _System or None) – Destination system. If None,
system_nameis looked up in the configuration’s database and created if needed.system_name (str) – Destination system name, used when
systemis None.name_prefix (str) – Prefix (e.g. a frame label) for the configuration names, which are
f"{name_prefix}{seed}_{m1-m2-...}"and unique within a frame.max_attempts (int or None) – Sampling attempts before giving up (default 50 * n_samples).
rng (int, numpy Generator or None) – Seed / generator for reproducibility.
store_properties (bool) – Store size, spread, motif, edge count, and source molecule list as
*#ExtractClusters#scanproperties on each configuration.seen (set or None) – Molecule sets already emitted (as frozensets); updated in place. Pass the same set across calls on the same frame to avoid duplicates.
- Returns:
New configurations; one metadata dict per cluster with keys
name, n, molecules, seed, order, rg, dmax, n_edges, degrees, motif, bin; and aninfodict withedges(the bin edges used, or None),attempts,per_keyquota,n_moleculesandn_contactsof the frame’s graph, andwarning(a message or None) if fewer than requested were produced.- Return type:
(configurations, records, info)
- extract_clusters_step.cluster_sampling.grow_connected(adj, seed, n, rng)[source]¶
Grow a connected n-molecule subgraph from
seed.Random frontier expansion: at each step a molecule adjacent to the current cluster is chosen uniformly and attached through a random one of its neighbours already inside. Uniform choice from the frontier is a cheap approximation to uniform connected-subgraph sampling; it mildly favours high-degree regions.
- Returns:
orderis the list of molecule indices in growth order;parentmaps each to the molecule it attached through (None for the seed). None if the connected component is smaller than n.- Return type:
(order, parent) or None
- extract_clusters_step.cluster_sampling.make_put_property(conf, tag='#ExtractClusters#scan')[source]¶
Return a closure storing
name+tagproperties onconf.Defines the property first if the database lacks it (the properties are normally pre-registered from
data/properties.csv).
- extract_clusters_step.cluster_sampling.molecule_neighbour_graph(frac_atoms, atom_mol, contact_mask, T, cutoff, periodic, cell_parameters)[source]¶
Molecule-level adjacency from atom contacts.
A~B if any contact atom of A is within
cutoff(Å, minimum image) of any contact atom of B.- Parameters:
frac_atoms ((N,3) ndarray) – Fractional coordinates (Cartesian if not periodic).
atom_mol ((N,) ndarray of int) – Molecule index of each atom.
contact_mask ((N,) ndarray of bool) – Which atoms define contact.
T ((3,3) ndarray) – Fractional->Cartesian transform (
xyz = uvw @ T); identity if not periodic.cutoff (float) – Contact distance, Å.
periodic (bool)
cell_parameters ((a, b, c, alpha, beta, gamma) or None)
- Returns:
Adjacency lists keyed by molecule index. Molecules with no contacts are absent.
- Return type:
dict[int, set[int]]
- extract_clusters_step.cluster_sampling.motif_names(n)[source]¶
The motif labels
classify_motif()can produce for n molecules.Named motifs for n <= 4; for larger n the labels are
e<edges>for every possible edge count of a connected graph, from n-1 (a tree) to n(n-1)/2.
- extract_clusters_step.cluster_sampling.pilot_spreads(adj, n, frac_centroids, T, periodic, spread_metric, n_mol, rng, n_pilot, motifs=None, coordination=None)[source]¶
Spread values of an unstratified pilot sample, used to place bin edges.
If
motifsorcoordinationis given only clusters passing those filters are sampled, so the bin edges describe the distribution the extraction will actually draw from (ring trimers, say, are compact and never reach the widest all-motif bin).
- extract_clusters_step.cluster_sampling.unwrap_shifts(order, parent, frac_centroids, periodic)[source]¶
Integer lattice shifts making each molecule contiguous with its parent.
Each molecule is shifted to the image nearest the neighbour it attached through, so the whole cluster is contiguous in space.
extract_clusters_step.extract_clusters module¶
Non-graphical part of the Extract Clusters step in a SEAMM flowchart
- class extract_clusters_step.extract_clusters.ExtractClusters(flowchart=None, title='Extract Clusters', extension=None, logger=<Logger extract_clusters_step.extract_clusters (WARNING)>)[source]¶
Bases:
NodeThe non-graphical part of a Extract Clusters step in a flowchart.
Extracts n-molecule clusters (trimers, tetramers, … larger clusters) from the current, typically periodic, condensed-phase configuration as unwrapped, non-periodic configurations in a new system, tagged with provenance. The clusters are connected subgraphs of the molecular contact graph, optionally stratified to be flat in a spread coordinate and balanced over topology. See
extract_clusters_step.cluster_samplingfor the algorithm.- parser¶
The parser object.
- Type:
configargparse.ArgParser
- options¶
It contains a two item tuple containing the populated namespace and the list of remaining argument strings.
- Type:
tuple
- parameters¶
The control parameters for Extract Clusters.
See also
TkExtractClusters,ExtractClustersParameters- analyze(indent='', P=None, results=None, system=None, sources=None, seed=None, motifs=None, coordination=None, **kwargs)[source]¶
Report the extracted clusters to step.out.
- Parameters:
indent (str) – An extra indentation for the output
P (dict) – The control parameters.
results ([(n, configurations, records, info)]) – The output of
extract_nmers()for each cluster size.system (molsystem _System) – The destination system.
source (molsystem _Configuration) – The source configuration.
- description_text(P=None)[source]¶
Create the text description of what this step will do. The dictionary of control values is passed in as P so that the code can test values, etc.
- Parameters:
P (dict) – An optional dictionary of the current values of the control parameters.
- Returns:
A description of the current step.
- Return type:
str
- property git_revision¶
The git version of this module.
- property property_tag¶
The suffix of the per-cluster properties, ‘#ExtractClusters#scan’.
- run()[source]¶
Run a Extract Clusters step.
- Returns:
The next node object in the flowchart.
- Return type:
seamm.Node
- property version¶
The semantic version of this module.
extract_clusters_step.extract_clusters_parameters module¶
Control parameters for the Extract Clusters step in a SEAMM flowchart
- class extract_clusters_step.extract_clusters_parameters.ExtractClustersParameters(defaults={}, data=None)[source]¶
Bases:
ParametersThe control parameters for Extract Clusters.
The keys are the parameters for this plug-in; each value is a dictionary describing that parameter (default, kind, units, enumeration, format, description, help).
- parameters{str: {str: str}}
A dictionary containing the parameters for the current step.
See also
ExtractClusters,TkExtractClusters,ExtractClustersStep- parameters = {'attempts per cluster': {'default': 50, 'default_units': '', 'description': 'Attempts per cluster:', 'enumeration': (), 'format_string': '', 'help_text': 'The sampling budget: the total number of attempts is this times the number of clusters requested. Attempts that duplicate an earlier cluster, fall outside the bin edges, or land in a full quota cell are rejected and count against the budget.', 'kind': 'integer'}, 'balance motifs': {'default': 'no', 'default_units': '', 'description': 'Balance motifs:', 'enumeration': ('yes', 'no'), 'format_string': '', 'help_text': 'Also balance the set over the topology of the contact graph within the cluster (chain / ring / star / ..., or the number of contacts for clusters of more than four molecules), jointly with the spread bins. Topology and spread are correlated -- rings only exist compact -- so some cells cannot fill and the set will come up short of the requested number; the summary shows which.', 'kind': 'boolean'}, 'bin edges': {'default': '', 'default_units': 'Å', 'description': 'Bin edges:', 'enumeration': (), 'format_string': '', 'help_text': "The bin edges of the spread metric, in Å, as an increasing comma- or space-separated list, e.g. '1.6, 2.0, 2.5, 3.5'. Clusters outside the outer edges are rejected. Note that sensible edges depend strongly on the cluster size and the system; 'quantile bins' is usually the better choice.", 'kind': 'string'}, 'centre coordination': {'default': 'any', 'default_units': '', 'description': 'Centre coordination:', 'enumeration': ('any',), 'format_string': '', 'help_text': "Accept only clusters whose most-connected molecule has this many contacts within the cluster: a value or SEAMM list such as '3' (star tetramers), '4' (a complete first shell) or '3:4'. 'any' accepts all. Applied at acceptance, so the set contains only such clusters instead of being post-filtered; the value is also stored on every cluster as the 'centre coordination' property.", 'kind': 'string'}, 'cluster sizes': {'default': '3', 'default_units': '', 'description': 'Cluster sizes (molecules):', 'enumeration': (), 'format_string': '', 'help_text': "The number of molecules per cluster. A comma- or space-separated list, e.g. '3, 4', extracts a set of each size from the same frame. Each must be at least 2.", 'kind': 'string'}, 'contact cutoff': {'default': 3.5, 'default_units': 'Å', 'description': 'Contact cutoff:', 'enumeration': (), 'format_string': '.2f', 'help_text': 'Two molecules are in contact if any of their contact atoms are within this distance (minimum image). A cluster is a connected set of molecules under this criterion. 3.5 Å between oxygens is the usual hydrogen-bond criterion for water.', 'kind': 'float'}, 'contact elements': {'default': 'all', 'default_units': '', 'description': 'Contact elements:', 'enumeration': ('all',), 'format_string': '', 'help_text': "The elements whose atoms define contact, e.g. 'O' or 'O, N'. 'all' uses every atom. Restricting to the heavy atoms that form the intermolecular contacts (e.g. O for water) makes the cutoff meaningful and the graph cheaper to build.", 'kind': 'string'}, 'make current': {'default': 'yes', 'default_units': '', 'description': 'Make the cluster system current:', 'enumeration': ('yes', 'no'), 'format_string': '', 'help_text': "Whether to make the cluster system (and its first configuration) the current one, so that a following Write Structure step writes the clusters. Choose 'no' when the source must remain current.", 'kind': 'boolean'}, 'motifs': {'default': 'any', 'default_units': '', 'description': 'Restrict to motifs:', 'enumeration': ('any',), 'format_string': '', 'help_text': "Accept only clusters whose contact-graph topology is one of the given motifs, e.g. 'ring', or 'ring, star' for several. 'any' accepts all. Trimers have 'chain' and 'ring'; tetramers 'chain', 'star', 'ring', 'paw', 'diamond' and 'K4'; larger clusters are labelled 'e<n>' by their number of contacts. Rare motifs use up the attempt budget quickly, so raise 'Attempts per cluster' if the set comes up short.", 'kind': 'string'}, 'name prefix': {'default': 'from configuration', 'default_units': '', 'description': 'Configuration name prefix:', 'enumeration': ('from configuration', 'none'), 'format_string': '', 'help_text': "Each cluster is named '<prefix><seed>_<m1-m2-...>' from the source molecules, which is unique within a frame. The prefix keeps the names unique across frames: 'from configuration' uses '<source configuration name>_' (the default, and the right choice when several frames are selected); 'none' uses no prefix; any other text is used literally (a variable such as '$frame_' works).", 'kind': 'string'}, 'number of bins': {'default': 3, 'default_units': '', 'description': 'Number of bins:', 'enumeration': (), 'format_string': '', 'help_text': 'The number of equal-quantile bins of the spread metric. The clusters are accepted so that the bins fill roughly evenly.', 'kind': 'integer'}, 'number of clusters': {'default': 50, 'default_units': '', 'description': 'Clusters per size:', 'enumeration': (), 'format_string': '', 'help_text': 'How many clusters of each size to extract from each selected configuration (frame). Fewer are produced if the configuration does not contain enough distinct connected clusters, or if stratification quotas cannot fill.', '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 seed, or an integer for a reproducible selection. The seed actually used is always printed in the output, so a 'random' run can be reproduced by entering that value here. A supplementary run over the same frames must use a DIFFERENT seed, or it will largely regenerate the same clusters.", 'kind': 'string'}, 'source configuration name': {'default': '', 'default_units': '', 'description': '', 'enumeration': (), 'format_string': 's', 'help_text': 'The configuration name, wildcard pattern or regular expression.', 'kind': 'string'}, 'source configurations': {'default': 'current', 'default_units': '', 'description': 'Configurations:', 'enumeration': ('current', 'all', 'last', 'first', 'name is', 'name matches', 'name regexp'), 'format_string': 's', 'help_text': 'Which configurations of each selected system to use: its current configuration, all of them, the last or first, or those whose name is / matches (shell wildcards) / matches the regular expression given.', 'kind': 'string'}, 'source system name': {'default': '', 'default_units': '', 'description': '', 'enumeration': (), 'format_string': 's', 'help_text': 'The system name, wildcard pattern or regular expression.', 'kind': 'string'}, 'source systems': {'default': 'current', 'default_units': '', 'description': 'Systems:', 'enumeration': ('current', 'all', 'name is', 'name matches', 'name regexp'), 'format_string': 's', 'help_text': 'Which systems to take the structures from: the current system, all systems, or those whose name is / matches (shell wildcards) / matches the regular expression given. A variable ($name) holding a list of configurations or of systems may also be given.', 'kind': 'string'}, 'spread metric': {'default': 'radius of gyration', 'default_units': '', 'description': 'Spread metric:', 'enumeration': ('radius of gyration', 'maximum centroid distance'), 'format_string': '', 'help_text': 'The compactness coordinate of a cluster, computed from the molecular centroids: the radius of gyration, or the largest centroid-centroid distance. Used for stratification and stored on each cluster.', 'kind': 'enum'}, 'store properties': {'default': 'yes', 'default_units': '', 'description': 'Store descriptors as properties:', 'enumeration': ('yes', 'no'), 'format_string': '', 'help_text': "Store the cluster size, spread, motif, number of contacts and source molecules on each configuration as '#ExtractClusters#scan' properties. They are carried through SDF/extxyz output.", 'kind': 'boolean'}, 'stratification': {'default': 'quantile bins', 'default_units': '', 'description': 'Stratify by spread:', 'enumeration': ('none', 'quantile bins', 'explicit bin edges'), 'format_string': '', 'help_text': "Whether to accept clusters so that the set is flat in the spread metric. 'quantile bins' places the bin edges at equal quantiles of a pilot sample of the frame, so the bins adapt to the cluster size and system; 'explicit bin edges' uses the edges given below; 'none' accepts clusters as sampled (biased towards the compact clusters that dominate the liquid).", 'kind': 'enum'}, 'system name': {'default': 'from source', 'default_units': '', 'description': 'Name the cluster system:', 'enumeration': ('from source',), 'format_string': '', 'help_text': "The name of the system that receives the clusters, created if it does not exist. 'from source' uses '<source system> clusters', with the system of the first selected structure. The clusters from all selected frames go into this one system.", 'kind': 'string'}}¶
extract_clusters_step.extract_clusters_step module¶
- class extract_clusters_step.extract_clusters_step.ExtractClustersStep(flowchart=None, gui=None)[source]¶
Bases:
objectHelper 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.
- my_description¶
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.
- Type:
{description, group, name}
- my_description[]¶
A description of the Extract Clusters step. It must be clear to non-experts.
- Type:
tuple
- my_description[]¶
Which group in the menus to put this step. If the group does not exist it will be created. Common groups are “Building”, “Calculations”, “Control” and “Data”.
- Type:
str
- my_description[]¶
The name of this step, to be displayed in the menus.
- Type:
str
- create_node(flowchart=None, **kwargs)[source]¶
Create and return the new node object.
- Parameters:
flowchart (seamm.Node) – A non-graphical SEAMM node
**kwargs (keyworded arguments) – Various keyworded 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:
See also
ExtractClusters
- create_tk_node(canvas=None, **kwargs)[source]¶
Create and return the graphical Tk node object.
- Parameters:
canvas (tk.Canvas) – The Tk Canvas widget
**kwargs (keyworded arguments) – Various keyworded 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:
See also
TkExtractClusters
- my_description = {'description': 'Extract molecular clusters (trimers, tetramers, ... larger n-mers) from a condensed-phase, typically periodic, configuration as unwrapped, non-periodic structures, e.g. for many-body training data and diagnostics for machine-learned force fields.', 'group': 'Building', 'name': 'Extract Clusters'}¶
extract_clusters_step.metadata module¶
This file contains metadata describing the results from Extract Clusters
extract_clusters_step.tk_extract_clusters module¶
The graphical part of a Extract Clusters step
- class extract_clusters_step.tk_extract_clusters.TkExtractClusters(tk_flowchart=None, node=None, canvas=None, x=None, y=None, w=200, h=50)[source]¶
Bases:
TkNodeThe graphical part of a Extract Clusters step in a flowchart.
- tk_flowchart¶
The flowchart that we belong to.
- Type:
TkFlowchart = None
- node¶
The corresponding node of the non-graphical flowchart
- Type:
Node = None
- canvas¶
The Tk Canvas to draw on
- Type:
tkCanvas = None
- dialog¶
The Pmw dialog object
- Type:
Dialog
- x¶
The x-coordinate of the center of the picture of the node
- Type:
int = None
- y¶
The y-coordinate of the center of the picture of the node
- Type:
int = None
- w¶
The width in pixels of the picture of the node
- Type:
int = 200
- h¶
The height in pixels of the picture of the node
- Type:
int = 50
- self[widget]¶
A dictionary of tk widgets built using the information contained in Extract Clusters_parameters.py
- Type:
dict
See also
ExtractClusters,TkExtractClusters,ExtractClustersParameters- create_dialog()[source]¶
Create the dialog. A set of widgets will be chosen by default based on what is specified in the Extract Clusters_parameters module.
- Parameters:
None
- Return type:
None
See also
- edit()[source]¶
Present a dialog for editing the Extract Clusters input
- Parameters:
None
- Return type:
None
See also
- handle_dialog(result)[source]¶
Handle the closing of the edit dialog
What to do depends on the button used to close the dialog. If the user closes it by clicking the “x” of the dialog window, None is returned, which we take as equivalent to cancel.
- Parameters:
result (None or str) – The value of this variable depends on what the button the user clicked.
- Return type:
None
- handle_help()[source]¶
Shows the help to the user when click on help button.
- Parameters:
None
- Return type:
None
- reset_dialog(widget=None)[source]¶
Layout the widgets in the dialog.
Only the stratification controls that apply to the chosen scheme are shown: the number of bins for ‘quantile bins’, the edges for ‘explicit bin edges’, and neither when stratification is off, so an unusable combination cannot be built in the editor.
- Parameters:
widget (Tk Widget = None)
- Return type:
None
See also
Module contents¶
extract_clusters_step A SEAMM plug-in for extracting molecular clusters from a periodic cell of molecules