Cooper-Beta
A deterministic strand-adjacency graph classifier for beta-barrel-like protein chains.
Cooper-Beta 1.0.0 reads PDB or mmCIF coordinates, regenerates secondary-structure annotations with DSSP, constructs one strand-adjacency graph per author chain, and reports a direct classification from three explicit rule groups. The package provides a command-line interface, a typed Python API, grouped evaluation utilities, and reproducible experiment scripts.
The BARREL class describes closure in the strand-adjacency graph. Functional annotation, membrane localization, and biological assembly interpretation can be added in downstream analyses.
Contents
- Installation
- Quick start
- Reading the output
- Algorithm
- Configuration
- Python API
- Evaluation and experiments
- Reproducibility
- Troubleshooting
- Release notes
- License
Installation
Requirements
| Requirement | Supported version | Purpose |
|---|---|---|
| Python | 3.10 or newer | Cooper-Beta runtime |
| DSSP | mkdssp 4.5.3 or newer |
Fresh secondary-structure and ladder annotation |
Install DSSP and Cooper-Beta:
conda install -c conda-forge 'dssp>=4.5.3'
pip install cooper-beta
cooper-beta --check-env
A successful environment check prints the resolved Python executable, DSSP executable, and DSSP version.
Optional dependency groups provide additional workflows:
| Installation | Adds |
|---|---|
pip install 'cooper-beta[eval]' |
Evaluation tables and metrics |
pip install 'cooper-beta[scripts]' |
Dataset, annotation, and plotting utilities |
pip install 'cooper-beta[ml]' |
Grouped machine-learning experiments |
pip install 'cooper-beta[full]' |
Evaluation, scripts, plotting, and machine learning |
For a source checkout, create the locked development environment with:
uv tool install 'conda-lock==3.0.4'
bash scripts/setup_env.sh --name cooperbeta --dev
Quick start
Run the included examples
The repository contains two real predicted structures curated as positive examples. Author chain A in both files is classified as BARREL by the default rules.
cooper-beta examples \
--workers 1 \
--prepare-workers 1 \
--out example_results.csv
| Example | Expected graph measurements | Expected class |
|---|---|---|
M4QT10.cif |
8 strands, 8 adjacencies, 8 cycle strands, rank 1 | BARREL, chain A |
A0A2R4ALS6.cif |
9 strands, 9 adjacencies, 8 cycle strands, rank 1 | BARREL, chain A |
examples/manifest.json records the source, target chain, scientific label, sequence length, confidence summary, and licence for each structure.
Analyze one file or a directory
cooper-beta path/to/structures \
--workers 8 \
--prepare-workers 4 \
--out results.csv
Directory discovery is recursive. Supported suffixes are .pdb, .cif, .mmcif, .pdb.gz, .cif.gz, and .mmcif.gz. The CLI writes:
results.csv: one row per analyzed author chainresults.csv.manifest.json: resolved settings, inputs, software environment, execution details, and output state
An existing output path is preserved by default. Select a new path or explicitly replace the existing result:
cooper-beta path/to/structures \
--out results.csv \
output.existing_artifact_policy=replace
Reading the output
Result classes
result |
Interpretation |
|---|---|
BARREL |
All three strand-graph rule groups passed |
NON_BARREL |
At least one rule condition failed |
ERROR |
Structure preparation or worker execution failed for the reported file or chain |
The reason field gives the passed-rule summary or the failed boundaries. error_code identifies failures such as structure parsing or DSSP execution. result_stage locates the outcome in preparation, decision, or worker processing.
Fixed CSV schema
The result CSV contains 14 columns in this order:
filename,source_path,author_chain_id,result,result_stage,
dssp_unassigned_residue_count,strand_count,strand_adjacency_count,
cycle_strand_count,cycle_strand_fraction,cycle_rank,reason,error_code,degraded
| Field | Definition |
|---|---|
filename |
Input filename |
source_path |
Resolved input path used by the run |
author_chain_id |
Author-chain identifier from the selected model |
dssp_unassigned_residue_count |
Included polymer residues with a C-alpha coordinate and an incomplete finite N/CA/C/O backbone |
strand_count |
Number of physical DSSP E strands after beta-bulge merging |
strand_adjacency_count |
Number of undirected ladder- or contact-supported graph edges |
cycle_strand_count |
Strand count in the largest cycle-supported component |
cycle_strand_fraction |
cycle_strand_count / strand_count, or 0 for an empty graph |
cycle_rank |
Number of independent graph cycles |
degraded |
Indicates an error row produced under degraded preparation policy |
All counts are non-negative integers. cycle_strand_fraction is constrained to [0, 1] and is serialized consistently with its two counts.
Algorithm
Processing flow
flowchart LR
accTitle: Cooper-Beta processing flow
accDescr: Coordinates are annotated by DSSP, converted into an author-chain strand graph, measured, and classified by three rule groups.
coordinates[PDB or mmCIF coordinates] --> annotation[Fresh DSSP annotation]
annotation --> strands[Physical E-strand nodes]
coordinates --> contacts[Multi-residue C-alpha contacts]
strands --> strand_graph["Strand-adjacency graph"]
contacts --> strand_graph
strand_graph --> measurements[Four graph measurements]
measurements --> rules[Three rule groups]
rules --> classification[Chain classification]
Structure preparation
The inference unit is one author chain in the configured coordinate model. Cooper-Beta retains author-chain identifiers, residue numbers, insertion codes, alternate locations, and declared polymer positions. mmCIF polymer positions come from label_seq_id; PDB positions are assigned by a unique alignment to the complete SEQRES declaration.
For coordinate-only mmCIF files, the supported input contract is one author chain with an unambiguous observed polymer. ATOM amino acids seed the polymer sequence. A modified amino acid stored as HETATM joins the polymer when it has a canonical backbone and a peptide connection to an included neighbor. The default maximum C-N distance is 1.8 Å.
Cooper-Beta regenerates DSSP annotations for the selected model and converts DSSP E ranges into strand segments.1 Segments covered by the same ladder side are merged into one physical strand, preserving beta bulges within a single node. A residue lacking a complete finite N/CA/C/O backbone remains part of the polymer record, receives dssp_assignment_available=false, and contributes to dssp_unassigned_residue_count.
Strand-adjacency graph
For an author chain, let the undirected graph be $G=(V,E)$, where each node in $V$ is one physical strand. An edge is supported by either:
- a DSSP ladder connecting two strands; or
- at least two C-alpha contact pairs separated by at most 6.8 Å, with at least two distinct contacting residues on each strand.
The graph is deterministic for a fixed coordinate model, DSSP release, and resolved configuration. The contact distance and support counts are configurable under strand_adjacency.
Graph measurements
Tarjan low-link traversal identifies bridge edges. Removing those bridges leaves the edges that participate in at least one cycle. Cooper-Beta reports:
- Strand adjacency count: the number of undirected edges in the graph.
- Cycle strand count and fraction: the number of strands in the largest connected component formed by non-bridge edges, reported together with its fraction of all graph strands. An empty graph has a fraction of zero.
- Cycle rank: the number of independent cycles, calculated from the graph's edge, node, and connected-component counts.
Bridge detection and graph measurement scale linearly with the combined number of graph nodes and edges.
Direct classification
The default classifier requires all three rule groups to pass at inclusive boundaries:
| Rule group | Default condition |
|---|---|
strand_adjacency_count |
$A \ge 8$ |
cycle_strand_count / cycle_strand_fraction |
$S \ge 4$ and $F \ge 0.05$ |
cycle_rank |
$R \ge 1$ |
The decision is
$$ \texttt{BARREL} = (A\ge 8) \land (S\ge 4) \land (F\ge 0.05) \land (R\ge 1). $$
A chain receives NON_BARREL when this conjunction is false. The four measurements remain available as continuous or count-valued features for learned classifiers.
Configuration
All behavior-changing values are defined in config.py, with defaults in config.yaml. CLI overrides use Hydra dot notation.
Scientific defaults
| Setting | Default | Unit or meaning |
|---|---|---|
strand_adjacency.maximum_ca_distance_angstrom |
6.8 |
Å |
strand_adjacency.minimum_contact_pair_count |
2 |
C-alpha pairs |
strand_adjacency.minimum_contact_residue_count_per_strand |
2 |
Distinct residues per strand |
rules.strand_adjacency_count.minimum |
8 |
Graph edges |
rules.cycle_strand_count_fraction.minimum_count |
4 |
Cycle-supported strands |
rules.cycle_strand_count_fraction.minimum_fraction |
0.05 |
Fraction of graph strands |
rules.cycle_rank.minimum |
1 |
Independent cycles |
Override values directly on the command line:
cooper-beta path/to/structures \
--out results.csv \
runtime.native_threads_per_process=1 \
strand_adjacency.maximum_ca_distance_angstrom=6.8 \
rules.strand_adjacency_count.minimum=8 \
rules.cycle_strand_count_fraction.minimum_count=4 \
rules.cycle_strand_count_fraction.minimum_fraction=0.05 \
rules.cycle_rank.minimum=1
Python mappings use the same keys:
from cooper_beta import build_config
config = build_config(
{
"runtime.workers": 8,
"runtime.prepare_workers": 4,
"rules.cycle_rank.minimum": 1,
}
)
Run cooper-beta --help for the complete interface, defaults, output behavior, and failure semantics.
Python API
detect returns a typed PipelineRunResult. A CSV is written when output is supplied or write_csv=True is selected.
from cooper_beta import detect
run = detect(
"path/to/structures",
workers=4,
prepare_workers=2,
output="results.csv",
)
print(run.result_counts)
for row in run.rows:
print(
row.filename,
row.author_chain_id,
row.result,
row.strand_adjacency_count,
row.cycle_strand_count,
row.cycle_strand_fraction,
row.cycle_rank,
)
Common public interfaces are:
| Interface | Purpose |
|---|---|
detect(...) |
Run end-to-end chain classification |
build_config(...) |
Build and validate typed settings |
PipelineRunResult |
Access rows, inputs, output path, settings, and class counts |
DetectionResult |
Access one validated 14-column chain result |
ProteinLoader |
Parse structures and obtain per-chain preparation results |
StrandAdjacencyGraph |
Represent an immutable author-chain graph |
StrandGraphMeasurements |
Store the four measured graph values |
User-facing exceptions derive from CooperBetaError. Specific subclasses identify invalid configuration, unusable inputs, structure parsing, DSSP availability or execution, missing chains, changed inputs, and output publication failures.
Evaluation and experiments
Direct-classifier evaluation
Install the evaluation extra and provide separate positive and negative structure collections:
cooper-beta-eval \
--positives path/to/positive_structures \
--negatives path/to/negative_structures \
--positive-manifest path/to/positive_truth.csv \
--negative-manifest path/to/negative_truth.csv \
--metric-level both \
--metric-error-policy strict \
--save-dir evaluation-results
Each target-chain manifest has four columns:
filename,source_path,structure_sha256,target_author_chain_id
The evaluator reports target-chain metrics and any-positive-chain file metrics separately. Metrics with an undefined denominator are stored as null values with an accompanying *_defined field.
Learned classifier and robustness analyses
scripts/nested_grouped_decision_experiment.py evaluates learned models from four features:
strand_adjacency_count,cycle_strand_count,cycle_strand_fraction,cycle_rank
Family groups remain intact across held-out folds. scripts/perturbation_eval.py evaluates sensitivity to controlled coordinate noise. scripts/annotate_bfvd_candidates_blastp.py supports sequence annotation of screened candidates.
Adapters for Foldseek, IsItABarrel, and PRED-TMBB2 are documented under external_methods. Their normalized outputs share explicit author-chain identifiers and can be compared with Cooper-Beta evaluation tables.
Reproducibility
Cooper-Beta records the resolved configuration, discovered inputs, package version, DSSP executable and version, execution settings, and output state in the run manifest. Input and output ordering are deterministic. Preparation caching uses the same resolved scientific inputs that define the prepared payload.
The repository provides two locked environment routes:
uv.lockfor Python package resolutionenvironment.ymlandconda-lock.ymlfor Python plus DSSP
For comparative studies, define target chains and family groups before fitting models, retain complete held-out predictions, and report the Cooper-Beta version, DSSP version, resolved settings, grouping strategy, and metric policy. Dataset-construction scripts are available under data/scripts.
Troubleshooting
| Symptom | Likely cause | Action |
|---|---|---|
DSSP: not found |
DSSP is absent from PATH |
Install dssp>=4.5.3 or set runtime.dssp_bin_path=/path/to/mkdssp |
Unsupported DSSP version |
The resolved DSSP predates 4.5.3 | Update DSSP and rerun cooper-beta --check-env |
OUTPUT_ARTIFACT_EXISTS |
The output CSV or manifest already exists | Choose a new --out path or set output.existing_artifact_policy=replace |
STRUCTURE_PARSE_FAILED |
The structure or declared polymer mapping is incomplete or ambiguous | Validate the selected model, author chains, SEQRES, and mmCIF polymer categories |
DSSP_FAILED |
DSSP could not annotate the prepared coordinate model | Inspect the reported DSSP message and validate the selected model with DSSP 4.5.3 or newer |
| Expected chain is absent | Label and author-chain identifiers differ | Inspect the structure's author-chain identifiers and the author_chain_id column |
| A large run uses too many processes | Worker counts exceed the desired resource allocation | Set --workers, --prepare-workers, and runtime.native_threads_per_process explicitly |
For a minimal diagnostic, run one structure with one worker and preserve the error message:
cooper-beta path/to/structure.cif \
--workers 1 \
--prepare-workers 1 \
--out diagnostic.csv
Release notes
1.0.0
Initial public release.
- Builds physical strands from fresh DSSP
Eranges and merges beta-bulge fragments assigned to one ladder side - Combines DSSP ladder adjacencies with multi-residue C-alpha contacts
- Measures
strand_adjacency_count,cycle_strand_count,cycle_strand_fraction, andcycle_rank - Applies three configurable direct-classifier rule groups
- Produces a fixed 14-column chain result and a bound run manifest
- Supports PDB, mmCIF, and configured gzip-compressed inputs
- Provides typed configuration, grouped evaluation tools, locked environments, and two curated positive examples
License
Cooper-Beta source code is released under the MIT License. The files in examples/ retain the CC BY 4.0 licence recorded in examples/manifest.json.
References
-
Van Ginkel, G. et al. (2025). "DSSP 4: FAIR annotation of protein secondary structure." Protein Science. https://doi.org/10.1002/pro.70208 ↩
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file cooper_beta-1.0.0.tar.gz.
File metadata
- Download URL: cooper_beta-1.0.0.tar.gz
- Upload date:
- Size: 505.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fd55f1744ef4fcf00a426fae8db25a15e2d6ce11e354963721de2b6a4ee1d6a0
|
|
| MD5 |
e7a75d37124667fdcd2e741dbad281e6
|
|
| BLAKE2b-256 |
79d52e2ca458e5c20f13b02110da30a52b8512b2cd6dacfc161f00efef4a32c2
|
Provenance
The following attestation bundles were made for cooper_beta-1.0.0.tar.gz:
Publisher:
publish.yml on GeraltZeroZhong/Cooper-Beta
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
cooper_beta-1.0.0.tar.gz -
Subject digest:
fd55f1744ef4fcf00a426fae8db25a15e2d6ce11e354963721de2b6a4ee1d6a0 - Sigstore transparency entry: 2475922038
- Sigstore integration time:
-
Permalink:
GeraltZeroZhong/Cooper-Beta@81144e9a6096d9516807d0c10a27825df4aca461 -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/GeraltZeroZhong
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@81144e9a6096d9516807d0c10a27825df4aca461 -
Trigger Event:
release
-
Statement type:
File details
Details for the file cooper_beta-1.0.0-py3-none-any.whl.
File metadata
- Download URL: cooper_beta-1.0.0-py3-none-any.whl
- Upload date:
- Size: 107.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5b8a99289ff61eab9fde28570ca87cb41fbdbb8cf4032de762c03fbdd612694d
|
|
| MD5 |
372ceca1a1b64fb9a6d3b8423818efa2
|
|
| BLAKE2b-256 |
ecd640b5dfb0e452469b4c52a0c9207910b688c810b830d257075624d1b357c7
|
Provenance
The following attestation bundles were made for cooper_beta-1.0.0-py3-none-any.whl:
Publisher:
publish.yml on GeraltZeroZhong/Cooper-Beta
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
cooper_beta-1.0.0-py3-none-any.whl -
Subject digest:
5b8a99289ff61eab9fde28570ca87cb41fbdbb8cf4032de762c03fbdd612694d - Sigstore transparency entry: 2475922077
- Sigstore integration time:
-
Permalink:
GeraltZeroZhong/Cooper-Beta@81144e9a6096d9516807d0c10a27825df4aca461 -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/GeraltZeroZhong
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@81144e9a6096d9516807d0c10a27825df4aca461 -
Trigger Event:
release
-
Statement type: