Repository navigation
Clustering Conformations
FleXgeo2 uses HDBSCAN to cluster conformations from local backbone geometry. It supports two clustering workflows:
- per-residue clustering, where each residue is clustered independently in
(curvature, torsion)space - residue-range clustering, where a selected residue window is converted into one combined geometric signature per conformation
HDBSCAN labels -1 mean noise or unassigned conformations.
Run:
flexgeo2 path/to/ensemble.pdb --cluster-residuesPython equivalent:
from flexgeo2 import AnalysisConfig, ClusteringConfig, FlexGeo2App
result = FlexGeo2App().run(
AnalysisConfig(
pdb_file="path/to/ensemble.pdb",
clustering=ClusteringConfig(cluster_residues=True),
)
)Each residue is clustered using only that residue's curvature and torsion values across models.
Run:
flexgeo2 path/to/ensemble.pdb --cluster-residue-range 45-54You can repeat the option:
flexgeo2 path/to/ensemble.pdb \
--chain A \
--cluster-residue-range 45-54 \
--cluster-residue-range 90-99Python equivalent:
from flexgeo2 import AnalysisConfig, ClusteringConfig, FlexGeo2App
result = FlexGeo2App().run(
AnalysisConfig(
pdb_file="path/to/ensemble.pdb",
chains=["A"],
clustering=ClusteringConfig(
cluster_residue_ranges=["45-54", "90-99"],
),
)
)Residue-range clustering concatenates curvature and torsion values across the selected window into one feature vector per conformation, then runs one HDBSCAN solution for the whole region.
Tune cluster size and sample behavior with:
flexgeo2 path/to/ensemble.pdb \
--cluster-residues \
--cluster-min-size 8 \
--cluster-min-samples 4Python equivalent:
ClusteringConfig(
cluster_residues=True,
min_cluster_size=8,
min_samples=4,
)-
min_cluster_size(smallest cluster, in models) defaults to 5% of the models, at least 5: 5 for up to 100 models, 15 for 301, 50 for 1000. -
min_samplesdefaults to 5, ormin_cluster_sizeif that is smaller. - A residue or range may form a single cluster (HDBSCAN's
allow_single_cluster). Without it, HDBSCAN has to split every residue into at least two clusters or call all of it noise, even when the residue has one state.
These were chosen on synthetic ensembles with known states (20 to 1000 models, 5 and 10 degree dihedral noise; residues with one state, two states 50/50 or 80/20, and three states) and checked on pdb2lj5.pdb:
- Residues with one state form one cluster in 95-100% of cases; with the earlier defaults (fixed size 5, no single cluster) they never did: they were split or all noise. On 2LJ5 the earlier defaults split all 76 residues, up to 12 clusters each; the new ones split 2 (THR12 and LEU71).
- Per residue, switches between states are found as well as before, and minority states down to 5% of the models can form their own cluster. In residue ranges, a minority state (20% of the models) carried by a single residue of a ten-residue window can now merge into the main cluster; the earlier defaults only partly separated it.
- A fixed size of 5 splits single-state residues more often as the ensemble grows. HDBSCAN's own
min_samplesdefault (equal tomin_cluster_size) smooths so much at 1000 models that clear two-state ranges merge.
Set --cluster-min-size to require larger states (or to find smaller ones), and --cluster-min-samples to change how conservative the density estimate is.
HDBSCAN labels a model as noise (-1) when it lies outside the dense core of every cluster. Noise does not mean the conformation is wrong or rare: in a residue with one broad state, around half of the models are often noise, the tail of that state. Read n_clusters for the number of states and noise_fraction for how spread out they are.
Per-residue clustering results are available at result.residue_clustering.
residue_clusters = result.residue_clustering
assert residue_clusters is not None
residue_clusters.summary_df.sort_values(
["n_clusters", "noise_fraction"],
ascending=[False, True],
).head(15)Residue-range clustering results are available at result.residue_range_clustering.
range_clusters = result.residue_range_clustering
assert range_clusters is not None
range_clusters.summary_dfPer-residue clustering writes clusters/:
-
clusters/assignments.csv: the cluster of every model at every residue, with the residue's curvature and torsion -
clusters/residues.csv: per residue, the number of clusters and the noise fraction -
clusters/clusters.png: the cluster of every model (rows) at every residue (columns), with the number of clusters per residue above; light grey is noise, and clusters 18 and above share dark grey ("Other clusters (18+)")
Labels are assigned independently at each residue, so cluster 0 at one residue is unrelated to cluster 0 at another. To look at residues in detail, add --plot-residues (e.g. --plot-residues 45,A:50-52): each chosen residue gets a curvature vs torsion plot coloured by cluster in residue_plots/. From Python, notebooks/04_clustering_conformations.ipynb shows how to draw the same plot from assignments_df.
Residue-range clustering writes range_clusters/:
-
range_clusters/assignments.csv: the cluster of every model for each range, with PCA plot coordinates -
range_clusters/ranges.csv: per range, the number of clusters and the noise fraction -
range_clusters/<chain>_<start-end>.png: the models on the first two principal components, coloured by cluster
The README.md in the output folder lists the residues with the most clusters and the result of each range. When every model in a range is labelled noise, FleXgeo2 suggests a smaller --cluster-min-size in both the README and the terminal summary.
n_clusters counts non-noise HDBSCAN clusters.
noise_fraction is the fraction of conformations labeled -1.
models is the number of conformations clustered; for ranges, residues is the number of residues in the range.
cluster is the assigned HDBSCAN cluster label for a conformation.
cluster_probability is HDBSCAN's confidence-like membership probability.
For residue-range clustering, pc1 and pc2 are PCA projection coordinates used for plotting the high-dimensional residue-window signature.
For a runnable version of this workflow, see notebooks/04_clustering_conformations.ipynb.