Release Notes
Version 1.1
v1.1.0 (Unreleased)
This release substantially expands the feature-engineering surface: a unified feature-preprocessor family (embedding / structure / annotation sources), a numerical CPP mode, a configuration-sweep wrapper, sequence-window sampling, site-localization metrics, and an opt-in golden-pipeline API.
Added
Data Handling
EmbeddingPreprocessor: Per-residue protein language model (PLM) embeddings.encodenormalizes raw embeddings into a[0, 1]per-residuedict_num(minmax/quantile/sigmoid) forrun_num();build_scales/build_catcollapse them into pseudo-scales forrun().fetch_embeddings([embed]extra) downloads a curated PLM (ESM-2, ESM-1b, ProtT5, ProstT5) from the Hugging Face Hub and computes per-protein (mean/max/cls pooling) or per-residue embeddings;pool_embeddingsreduces per-residue arrays to per-protein vectors. The new[embed]extra isolates the heavytorch/transformersdependencies.StructurePreprocessor([pro]): Converts PDB / CIF / AlphaFold files (and PAE sidecars) into[0, 1]-normalized per-residue tensors (get_dssp,encode_dssp,encode_pdb,encode_pae,get_domains,encode_domains,build_scales,build_cat).AnnotationPreprocessor([pro]): Fetches UniProt (or ingests user / predictor) per-residue PTM and functional-site annotations and encodes them into tensors (fetch_uniprot,ingest,register_feature,encode,build_scales,build_cat,to_df_seq).combine_dict_nums: Concatenates per-residue tensors (embedding / structure / annotation) along the feature axis into one combined
CPP.run_numinput.get_labels: Derives a binary
intlabel vector from a sequence DataFrame’s label column (positive_labelmapped to1, everything else to0) — the single-call form of the recurring(df[col] == x).astype(int).to_numpy()expression.combine_dict_nums(): Concatenates per-residue tensors (embedding / structure / annotation) along the feature axis into one combinedrun_num()input.pad_parts(): Pads the sequence-part columns of adf_partsDataFrame to a uniform length with a gap symbol (lengthtarget or each column’s per-part max; N-terminal, C-terminal, or symmetricboth). The selectedlist_partscolumns are padded (default all) and a padded copy is returned (non-selected columns and the index unchanged; input never mutated). Enables analyzing short, variable-length parts at a finer, uniform resolution via pad →CPP(accept_gaps=True) → larger uniformn_split_maxthan the shortest real part allows.
Feature Engineering
CPPGrid:Tool-style wrapper (run+eval) that runs a parallel grid sweep ofCPPconfigurations in one call; configurations differing only inn_filtercollapse into a single run.eval(sort_by=...)scores the configurations (avg_ABS_AUCby default) best-first.run_num(): Numerical mode sourcing per-residue values from a pre-sliced tensor (dict_num_parts) instead of an amino-acid → scale lookup — embedding / structure / annotation features through the same pipeline and output schema asrun().run_composit(): Composition mode — build adf_featof composition features (iFeature-style descriptors [Chen18]) scored with CPP’s discriminative statistics.composition="aac"(amino-acid composition) is positional CPP — a one-hot identity scale set with the whole-partSegment(1,1)split, so it yields<PART>-Segment(1,1)-<AA>features with positions drawn by the feature map.composition="dpc"(dipeptide) /"kmer"(generalk) are non-positional (a k-mer is an adjacent-tuple property, not a per-residue scale): the20 ** kk-mers are scored and filtered by adjusted AUC (topn_filter), a min-occurrence guard (min_count), and optional correlation dedup (max_cor). The composition matrices themselves come fromkmer_composition()(which documents the compositional approaches).CPP bootstrap / stability annotation (
CPPconstructor:bootstrap,bootstrap_kws): Opt-in resampling-based stability annotation, a thin wrapper applied uniformly byrun(),run_num(), andrun_composit(). Withbootstrap=Truethe data is resampledbootstrap_kws['rounds']times (bootstrap_kws['resample']='reference'fixes the test group and resamples only the reference group; also'both'/'test'; per-group draw sizebootstrap_kws['frac'], with replacement) and re-selected each round to score how often each feature is selected, then the ordinary full-data run is returned with a ``selection_frequency`` column (0 to 1) added. The selected features are exactly those of a normal run (n_filterstays the selection criterion);selection_frequencyflags which are reproducible under resampling — a trust / interpretability aid, not a change to the list or accuracy. The tuned config lives in onebootstrap_kwsdict (keysrounds/resample/frac, parallel tosplit_kws);bootstrap=Truedefaults todict(rounds=20, resample='reference', frac=0.8)and any omitted key falls back to its default. The defaultbootstrap=Falseis byte-identical to previous versions. Reuses the constructorrandom_state.CPP.run ``redundancy=’legacy’|’exact’`` (also
run_num()): Opt-in position-overlap criterion for the redundancy-reduction step. The default'legacy'is byte-identical to previous versions (published signatures stay reproducible);'exact'compares the actual residue positions — an interpretability enhancement (a more concentrated signature, fewer redundant subcategories) that does not change predictive performance. For a stronger, more efficient reduction, seesimplify().CPP.simplify ``candidate_search=’fast’``: Opt-in heuristic capping the candidate scales evaluated per feature, for a large speed-up on big scale pools (mainly
greedy). The default'exact'reproduces the previous result;'fast'is statistically equivalent (kept-feature Jaccard ≥ 0.95, ΔavgABS_AUC ≤ 0.005 on the canonical data).SequenceFeature.get_labels_ovr / get_labels_ovo: Convert multi-class
labelsinto binary sets forCPP— one-vs-rest (all samples kept) or one-vs-one (per class-pair, each pair’s value source row-matched).SequenceFeature.get_labels_quantile / get_labels_tiered: Discretize a continuous target into binary
labels— a single quantile cut, or a fixed positive set swept against stepwise-lowered negative cuts (each tier row-matched).SequenceFeature.scale_composition: Scale-composition baseline featurizer that turns sequences + scales into a
(n_seq, n_scales)matrix by averaging each scale over a sequence span (list_parts=None→ wholejmd_n+tmd+jmd_c), dropping missing / non-canonical residues — the sequence’s mean profile in scale-space (the scale-based analogue of amino-acid composition). The no-positional-split baseline to compare againstfeature_matrix/ CPP; optionalreturn_df=Truefor a labeled frame.feature_matrix(): Turnsrun_num()-selected features back into a model matrixX— the numerical analog offeature_matrix(). Reconstructs eachPART-SPLIT-SCALEvalue from the per-residue tensors indict_num_parts, with per-part lengths taken fromdf_parts(the same length sourcerun_num()uses), re-applying the split to the part’s residue axis rather than the JMD-offsetpositionsdisplay numbering.Xis therefore byte-identical to the valuesrun_num()computed and preserves the per-residue context that per-AA-averaged sequence features discard.SequenceFeature.aa_composition: Amino-acid-composition (AAC) baseline featurizer that turns sequences into a
(n_seq, 20)matrix — the fraction of each of the 20 canonical amino acids (ut.LIST_CANONICAL_AAcolumn order) over a sequence span (list_parts=None→ wholejmd_n+tmd+jmd_c), dropping gaps / non-canonical residues so each row sums to 1. Fully vectorized; the no-positional-split residue-frequency baseline to compare againstfeature_matrix/ CPP; optionalreturn_df=Truefor a labeled frame.SequenceFeature.dipeptide_composition: Dipeptide-composition (DPC) baseline featurizer that turns sequences into a
(n_seq, 400)matrix — the fraction of each of the 400 ordered adjacent canonical amino-acid pairs (AA, AC, ..., YY) over a sequence span, dropping gaps / non-canonical residues before pairing (adjacencies span dropped residues and cross concatenated part boundaries); each row with at least two canonical residues sums to 1. Captures local sequential order that plain composition discards; fully vectorized; optionalreturn_df=Truefor a labeled frame.SequenceFeature.kmer_composition: General k-mer-composition baseline featurizer — the fraction of each of the
20 ** kordered overlapping k-mers of adjacent canonical residues over a sequence span, a(n_seq, 20 ** k)matrix (columns initertools.product(ut.LIST_CANONICAL_AA, repeat=k)order).kselects the composition:k=1is amino-acid composition (identical toaa_composition),k=2dipeptide composition (identical todipeptide_composition), and higherk(up to 4) captures longer local sequential order. Same non-canonical-dropping, gap-free-span, each-row-sums-to-1 semantics as thek=1/k=2special cases; fully vectorized (onebincountover base-20 k-mer codes); optionalreturn_df=Truefor a labeled frame.return_scales=Truealso returns the CPP-ready(df_scales, df_cat): fork=1the(20, 20)one-hot identity scale set + amino-acid-classdf_cat(feed torun()with a whole-partSegment(1,1)split to get amino-acid composition as a realdf_feat/ feature map); fork>=2df_scalesisNone(a k-mer is not a per-residue scale) anddf_catcategorizes the k-mers by residue class.SequenceFeature.get_df_parts_from_windows: Assemble a reference
df_partsfrom per-part window sets (e.g.AAWindowSampler.sample_syntheticoutput).SequenceFeature.get_seq_kws: Return one protein’s
{jmd_n_seq, tmd_seq, jmd_c_seq}get_df_parts_from_windows(): Assemble a referencedf_partsfrom per-part window sets (e.g.sample_synthetic()output).get_seq_kws(): Return one protein’s{jmd_n_seq, tmd_seq, jmd_c_seq}as a ready-to-splatseq_kwsdict (by entry or position), parts taken fromdf_partsso the residues stay bound to the feature geometry — removing the manual slicing glue when feedingprofile()/feature_map(e.g. sample-level SHAP plots).get_feature_descriptions(): One standardized, human-readable sentence perPART-SPLIT-SCALEfeature id (region + split + AAontology scale name / category). Additive (the'feature'id is unchanged); fills an optional'feature_description'column.pre_select_scales(): Metadata-only pre-filter that drops scales by AAontologycategory(cat_out) /subcategory(subcat_out) viadf_cat— the preparation step beforeselect_scalesorfilter_coverage(no clustering).select_scales(): Wrapper aroundfit()that returns the redundancy-reduced scale subset (one medoid per cluster) directly, ready forCPP.select_proteins(): Protein-level redundancy reduction over a per-protein feature matrixX— clusters proteins, selects one medoid per cluster, annotatesdf_seqwithcluster/is_representative/dist_to_rep— the numerical counterpart tofilter_seq().AAclustPlot.centers / medoids accept ``df_scales``: Pass scales via
df_scales(transposed internally) instead ofcenters(np.array(df_scales).T, ...); pass proteins / embeddings / CPP features viaX(used as-is). The explicitXsignature is unchanged.
Prediction
ReliabilityModel: Per-sample prediction reliability — quantifies how much to trust a prediction, separately from the score itself (a model can be confident about a0.55and worthless about a1.0out-of-distribution score). Wraps a fitted predictor (anAAPred, aTreeModel, or any scikit-learn classifier) plus its training data and reports, per sample: stability (ensemble/bootstrapscore_stdand a confidence interval), an applicability-domain out-of-distribution signal (k-NN distance, Mahalanobis, leverage →ood_score/in_domain), calibrated sharpness (margin/entropy), a marginal split-conformal prediction set that can abstain, and a headlinereliableflag (in-domain, stable, and a confident conformal singleton).fit/predict/eval; core scikit-learn only, no new required dependency.ReliabilityModelPlot: VisualizesReliabilityModeloutput — a per-sampleranking(each prediction’s score with its uncertainty interval, colored by trust status), a calibration curve (reliability_diagram), the out-of-distribution score distribution (ood_hist), and a score-vs-OODtrust_mapcolored by thereliableflag.eval(): Newbaselineoption to compare the bound (CPP) features against simple, non-positional composition baselines built internally fromdf_seq—'scale'(scale_composition()),'aac'(aa_composition()), and'dpc'(dipeptide_composition());baseline=Trueselects the scale baseline. Each baseline is cross-validated with the same models and folds and appended todf_evalunder a new leadingfeaturescolumn ('cpp'for the bound rows), so the whole “CPP vs baseline” comparison comes from one call. Purely additive: withbaseline=None(default)df_evalis byte-identical to before (nofeaturescolumn).eval()(bar plot) reads thefeaturescolumn as the hue, so it draws thecppand baseline bars side by side instead of averaging them.eval(): Newkind='heatmap'that renders any 2D score grid (rows x columns are the two sweep axes) as a square annotated heatmap and boxes the best cell(s) with a full-cell frame —highlightselects how many (a positive int for the top-N,"max"/"min", an explicit(row, col)/ list, orNone);vmin/vmax/cmap/cbar_labelstyle the color scale and its tick-side-edged colorbar. One call for the recurring “grid of scores -> seaborn heatmap -> mark the best configuration” block.predict_group(): Newkind='rank_scatter'— a per-protein rank scatter (proteins ranked by their maximum score and colored by group, with optional threshold lines), the standard sanity check for a deployed per-protein predictor. Plus a newband=Truemode forkind='hist'that colors each bar by the confidence band it falls into (delimited bythresholds) instead of by classlabels— for scoring unlabeled candidates. Both additions are purely additive; existing default outputs are unchanged.
Explainable AI
ShapModel — accession-based interface (
[pro]):fitaccepts entry-keyed soft labels (fuzzy_labels={'P05067': 0.6}) together withdf_seq;add_feat_impact/add_sample_mean_difacceptdf_seqand asamplesparameter taking row positions or entry names. The array-labelspath is unchanged;sample_positionsis a deprecated alias forsamples(removed in 1.2.0).ShapModel — unbiased fuzzy estimator, now the default (
[pro]):fitgainsfuzzy_aggregation, defaulting to the new'interpolate'estimator. It weights a soft label by exactlyp— fitting at 0 (S0) and at 1 (S1) and blendingp * S1 + (1 - p) * S0— the unbiased alternative to the biased threshold sweep, which stays available as a first-class option viafuzzy_aggregation='threshold'. Forinterpolate,n_rounds(default5) is a speed/stability dial:1is the fast exact two-fit estimate (~2x faster than the threshold default on the same cell),5adds light Monte-Carlo averaging, and the mean converges (run-to-run spread below ~5%) aroundn_rounds ≈ 15–20; a fixedrandom_statekeeps every run reproducible.CPPStructurePlot([pro]): Paints per-residue CPP / CPP-SHAP feature impact onto an interactive 3D protein structure, rendered with py3Dmol (no matplotlib structure fallback — the cartoon is always a real 3D view).map_structure( df_feat, pdb=...)(oruniprot=...to auto-fetch the AlphaFold model) returns aStructureView(show/write_html/_repr_html_). Supports an'impact'red-white-blue ramp and a'plddt'AlphaFold-confidence mode, withwhole/fade/zoomfocus. By default each feature’s full impact is painted on every residue it spans (app-fidelity colouring);normalize_by_span=Trueswitches to the span-normalized sum used byprofile()and thefeature_map()top per-position bar.plot_combinedreturns aCombinedViewshowing the py3Dmol cartoon next to thefeature_map()image (write_htmlexports the pair;savefig(path)saves the feature-map panel as a static PNG / PDF for papers — the 3D cartoon is interactive and has no headless image), reproducing the deployed cleavage app’s signature layout.interactivereturns a live ipywidgets explorer (added to the[pro]extra) where a site slider drives a userpredictorand repaints the linked 3D structure andfeature_map()together (debounced), the notebook-native version of the app’s per-site explore loop. A highlight (position) slider links the two panels live: picking a residue lights it up in the 3D cartoon and marks its feature-map column without re-predicting, and with theipympl(%matplotlib widget) backend the feature map becomes clickable for the same highlight (ipymplis optional — the slider is the always-present link, no extra dependency).plot_linkedreturns aLinkedView— a self-contained HTML where hovering a feature-map column highlights the corresponding residue in the 3Dmol cartoon (the app’s signature interaction);write_htmlexports it as a standalone, shareable page.explore(df_feat, sequence, df_seq=..., labels=..., model=...)is the integrated one call: it builds a built-in per-site predictor (compute the query window’s values for the fixed feature set, predict the probability, attach the per-site SHAP impact via a defaultShapModelrefit — norun()rediscovery) and dispatches to a selectableoutput('widget'/'html'/'static');modeltakes a name ('rf'/'svm'/'log_reg'), an estimator, or a list, and a custompredictor=(sequence, p1) -> df_featremains the escape hatch. Withoutput='html', passingsites=[...]bakes a multi-site live standalone page: a client-side JS slider switches the pre-computed prediction per P1 (feature map + structure restyle) with no kernel, keeping the column-residue linking (warned past 40 sites, hard-capped at 200).
PU Learning
dPULearn.fit — positives/unlabeled split input: for the common positive / unlabeled setup,
fitnow acceptsX_posandX_unlabeledseparately (an alternative toX+labels) instead of stacking them by hand and building a1/2label vector. After fitting, the newdPULearn.mask_neg_attribute holds the boolean mask of reliable negatives — over the rows ofX_unlabeledin the split mode, overXotherwise (equal to the manuallabels_[len(X_pos):] == 0result exactly).fitstill returnsselfand the existingfit(X, labels=...)path is unchanged.project(): Projects held-out samples from the same feature space into the fitted PC space (thePCicolumns ofdf_pu_) after PCA-based identification, so new proteins can be placed alongside the identified negatives.methodselects the reconstructed linear map —'lstsq'(default, affine least-squares) or'components'(exact PCA-geometry map); both are exact on the fitted samples and interpolate for new ones.pca()gainsdf_pu_add/names_add/colors_addto overlay one or more projected groups (a one-call four-group PCA); the default (df_pu_add=None) output is unchanged.
Sequence Analysis
AAWindowSampler: Samples fixed-length sequence windows for PU-learning and hard-negative-mining workflows (sample_same_protein,sample_different_protein,sample_motif_matched,sample_synthetic).scan_motif()([pro]): Scans candidate proteins for statistically significant PWM occurrences via MEME/FIMO, complementing the pure-Pythonsample_motif_matched()sampler.
Protein Engineering
SeqOpt — multi-objective protein engineering (core; only
mode="impact"needsaaanalysis[pro]): A newSeqOptoptimizer (withSeqOptPlot) performs machine-learning-guided directed evolution of one wild-type — searching the Pareto front across several objectives at once, with a model-boundSeqMutas the fitness engine and a re-implementation of NSGA-II for selection (this is protein engineering, not de novo design). Two guidance modes:mode="impact"refitsShapModeleach generation under fuzzy labeling to target the strongest-feat_impactresidues;mode="importance"walks positions by staticfeat_importance. The evolutionary toolbox is a complete pure-Python re-implementation (DEAP is a dev/test-only parity oracle; runtime stays DEAP-free):crossover(uniform / one- / two-point),mutation(substitution / shift),variation(varAnd / varOr),survival((mu+lambda) / (mu,lambda) / eaSimple),constraints(delta / closest-valid penalty), a single-objective Hall of Fame (hall_of_fame_), and a memory-bounded (chunked) vectorized non-dominated sort. Objectives accept anycallable(sequence) -> float(an external scikit / torch model or sequence-level tool / web API), cached per variant.runreturnsdf_pareto(objective columns +rank+crowding) backed by a cumulative Pareto archive;evalreports hypervolume / front size / spread / convergence. Visualization:SeqOptPlotcoverspareto_front(2-D / 3-D),parallel_coordinates,convergence(hypervolume + spread + per-objective best/mean/worst band),hypervolume,mutation_map(front substitution-enrichment heatmap) andgenealogy(mutational-lineage tree). Reproducible viarandom_state/seed.SeqMut model-guided mode (ML-guided directed evolution):
SeqMutis optionally model-aware — binding a fitted classifier (SeqMut(model=..., target_class=...), any object withpredict_proba) makesscan/suggest/mutatereportdelta_pred(the prediction-score shift in percentage points) andsuggestrank by it. Without a model,SeqMutstays the deterministic, model-free ΔCPP tool.combine(): Scores combined multi-mutation variants — several point mutations applied to one sequence and evaluated as a single design.SeqMutPlot:mutation_landscaperenders thedelta_predprediction-shift mutation-scan heatmap; newvariant_impact(ranked-variant bar) andepistasis(pairwise non-additivity) plots.
Metrics
comp_per_protein_ap(): Per-protein average precision for site-localization ranking, with an optionaltolerance=±kvariant for positional jitter.comp_detection_metrics(): Recall / precision / F1 / MCC at a fixed score threshold, pooled across per-residue predictions.comp_bootstrap_ci(): Seeded percentile confidence interval over a per-protein metric vector (returns{'mean', 'ci_low', 'ci_high'}).comp_smooth_scores(): Peak-preserving (max(smoothed, raw)), NaN-aware smoothing of per-residue score tracks.
Plotting
COLOR_SAMPLES_POS / COLOR_SAMPLES_NEG / COLOR_SAMPLES_UNL / COLOR_SAMPLES_REL_NEG: Public, named constants for the canonical sample-group colors (positive / negative / unlabeled / reliable-negative). They equal the
plot_get_cdict("DICT_COLOR")["SAMPLES_*"]values exactly, so a named constant replaces indexing the color dict by string key.
Golden Pipelines
aaanalysis.pipe (
aap): A second, opt-in convenience API of stateless, one-call golden pipelines over the AAanalysis primitives (import aaanalysis.pipe as aap).aap.find_features: Staged, interpretable CPP AutoML search. Stage 1 cross-validates the full Cartesian Part × Split × Scale grid and ranks each axis by its marginal-mean impact; Stage 2 refines the single highest-impact axis against
n_filter; Stage 3 refines the winning feature set (simplify()+ recursive feature elimination, each kept only if it is not Pareto-dominated). Selection is multi-objective: within each stage the Pareto-optimal-then-simplest configuration across allmetricwins, scored by the averaged cross-validated performance of one or moremodels. The winner is ranked by tree-based importance and drawn as the feature map. Thesearchgrade scopes the effort ("fast"is byte-identical to the explicit single-CPP path); it returns(df_feat, ax, df_eval)whereaxalso carries the publication eval figures (ax.eval) anddf_evalhas one<metric>_mean/_stdcolumn per metric plusstage/is_pareto/rank/is_selected.aap.predict_samples: Trains and cross-validates every
(feature set × model)combination over onedf_seqin a single call, returning the refit predictors and a tidy comparison table. Withplot=True(the default) it now also draws the model comparison bar plot (hue = model, one bar group per metric, cross-validationstderror bars) and returns itsAxesin the previously-unused middle slot, completing the(results, fig, evals)symmetry withfind_features/explain_features(figsize/dict_color/baselinestyle it).aap.plot_eval: Publication-ready evaluation figures of a
find_featuressweep — the high-dimensional Part × Split × Scale grid is decomposed into a series of clean 2Dviridisheatmaps (the two most-informative axes on each panel, the least on the slice), with a shared colorbar, the selected configuration starred, plus marginal-impact andn_filterpanels. Returns the list of figures so each drops straight into a paper; also usable standalone on afind_featureseval table.
Package
aa.__version__: The installed package version is exposed at top level via
importlib.metadata.CHANGELOG.md + deprecation policy: A root
CHANGELOG.md(Keep a Changelog format) gives a terse, developer-facing index alongside these narrative notes. From v1.x onward, any rename or removal of a public symbol ships at least one minor release carrying aDeprecationWarningfirst; an internaldeprecated(reason, version_removed)decorator marks such symbols. See Versioning and Deprecation Policy inCONTRIBUTING.rst.
Documentation
Prediction tasks concept page (Usage Principles): maps a biological question to the right workflow via a task table keyed on unit of comparison and reference construction, across the residue / domain / protein levels — the front door to the Protocols catalog.
A minimal CPP analysis tutorial (
tutorial0_minimal): the shortest end-to-end loop — load a dataset, run CPP, read out the signature.Documentation navigation: the sidebar is grouped into four sections — Overview, Guides (Tutorials · Protocols · Use Cases), Reference, and Project — and the landing page gains a “You want to… / Go to” routing table; the previously unwired Comparison Harness tutorial (
tutorial6_comparison_harness) is now reachable.Use Cases guide (third Guides subchapter): each use case showcases a published study end to end from bundled data. The first, Charting γ-secretase substrates by explainable AI (
use_case1_gamma_secretase), walks the full AAanalysis pipeline of Breimann and Kamp et al., Nat. Commun. 2025 on the bundledDOM_GSEC/DOM_GSEC_PUsets: AAlogo sequence logos of the three protein groups, AAclust redundancy-reduced scale sets, the CPP + TreeModel signature and feature map, dPULearn reliable-negative mining (with PCA and logo), a prediction benchmark (feature engineering × data expansion) plus a CPP/dPULearn optimization heatmap, and SHAP single-residue explanations for individual substrates (APP, N-cadherin).Standardized tutorial header box: every tool tutorial now opens with a uniform green You will learn box (Tool · Input · Output · Best used for · Related protocol · Related API), giving a one-glance answer to what tool, what goes in, what comes out, and where to go next and cross-linking the matching protocol and API reference.
Split API reference: the reference is now two pages, each listing its members directly at the top level. API documents the explicit building blocks (
import aaanalysis as aa) grouped by category; the new API (Pipelines) page documents the golden pipelines (import aaanalysis.pipe as aap), one function per pipeline. Golden pipelines are no longer mixed into the building-block page or the Tutorials section; Getting Started links both references.
Changed
TreeModel: per-round seeding fix — with a fixedrandom_state(or the globaloptions["random_state"]),fit()now reseeds each round torandom_state + iso the rounds are independent. Previously every round fit identical estimators, sofeat_importance_std(andpredict_proba()’spred_std) collapsed to exactly0and rounds 2..N were wasted. Fixed-seed importances change once (degenerate → real Monte-Carlo mean with non-zero std); therandom_state=Nonedefault is unchanged.Consistent auto_font sizing:
heatmap()/profile()/ranking()now default tofigsize=Noneand honor any explicitfigsizeas a fixed size, so “explicit figsize wins” holds package-wide (matchingfeature_map()); omittingfigsizeauto-sizes as before.heatmap()/profile()gain theseq_char_fillresidue-spacing option already onfeature_map(), andpredict_group()(kind='rank_scatter') joinsauto_font— its width grows with the number of ranked proteins whenfigsizeis omitted.Uniform plot return contract: Every public
*Plotmethod now returns a single(fig, ax)pair (forwarding attribute access toax, so existingax = plot(...); ax.set_title(...)code keeps working), replacing the previous mix of shapes. Breaking change, scheduled for the next major release:centers()/medoidsreturn(fig, ax)and expose the PCA-component DataFrame on thedf_components_attribute instead of as the second return value.CPP performance: The Cython feature-matrix kernel, macOS-safe threaded
n_jobs, scale / AA-index caching, and scale / sample batching land in this release, replacing the hour-long, low-CPU CPP runs of≤1.0.3— users on those versions should upgrade. When the compiled extension is missing and CPP falls back to the pure-Python kernel, the one-time notice is now aUserWarning(visible even withverbose=False).feature_matrix(): Newbatch=parameter accepts a list ofdf_partsbuilt in a single Cython pass (faster for many small part tables).SequenceFeature.feature_matrix: New
df_seq=/list_parts=parameters builddf_partsinternally (viaget_df_parts), collapsing theget_df_parts→feature_matrixtwo-step into one call. Exactly one ofdf_parts/df_seqis required; the existingdf_parts=path is unchanged (byte-identical).get_df_parts / NumericalFeature.get_parts: New
pos-anchor mode (tmd_len=) explodes each 1-based anchor into onejmd_n/tmd/jmd_crow (entry_win).get_df_partsis also several-fold faster (vectorized; output unchanged).n_jobs: Unified parallelism convention across
CPP/CPPGrid(1serial,-1all cores,N>1exactly N,Noneoptimized), with anoptions['n_jobs']global override.feature(): Titles the plot with the feature’s human-readable description, line-wrapped viashow_title(defaultTrue) andtitle_wrap_width(default45).load_dataset verbose reporting: New
verboseparameter (defaultFalse) reports how many entries each removal step (min_len,max_len, andnon_canonical_aa='remove') drops, making the previously silent filtering observable. The returned data is unchanged; to retain every entry usenon_canonical_aa='keep'.Docstring discoverability: Surfaced previously implicit API contracts at the docstrings users read (no behavior change) — the
get_parts→run_numcall order and[0, 1]normalization contract, and a[pro]install marker on the pro classes / functions.fit(): Flexible label handling vialabel_pos/label_unl/label_negmarkers (only unlabeled samples are candidates; pre-labeled negatives are kept and never re-selected). The negative count is set by exactly one ofn_neg(the total wanted) orn_unl_to_neg(drawn directly from the unlabeled pool); output uses the package convention (1positive,0negative,2unlabeled).Pooled, optionally concurrent web fetches:
fetch_alphafold/fetch_uniprotroute every request through a pooledrequests.Sessionand accept amax_workersparameter. Concurrency is off by default (parallel requests risk HTTP-429 throttling); when enabled, results reassemble in input order, so output is byte-identical.Performance (same output): Many internal hotspots were vectorized or parallelized with byte-identical results —
AAWindowSamplerfiltering / sampling,AAclustmedoid distances, the per-feature KLD path ineval(),encode_one_hot,comp_substitution_impact(),get_sliding_aa_window, and severalStructurePreprocessorencoders (encode_pdbcontact / disulfide / pLDDT, a shared per-entry chain-pick and alignment cache,get_dssp). Public APIs and outputs are unchanged.Developer tooling: A committed
pytest-benchmarksuite (tests/benchmarks/,[bench]extra) micro-benchmarks the hot entry points as a non-gating nightly; a numerical-equivalence tolerance policy defines three tiers (T1 byte-identical, T2allcloseplus identical discrete decisions, T3 statistically-equivalent within an agreed band) for output-affecting optimizations; and an advisory pyright ratchet (.github/pyright_baseline.txt) drives the type-contract count down per subpackage (now 887, every public-API signature pyright-clean). None gate a merge or change the public API.
Changed
Module rename: the
protein_designsubpackage is nowprotein_engineering, matching its user-facing name (AAMut/SeqMut/SeqOptare amino-acid mutation and directed-evolution tools). The public classes are unchanged and imported the same way (import aaanalysis as aa→AAMut,SeqMut,SeqOptand their plot classes); only a full-path import such asfrom aaanalysis.protein_design import SeqMutmust becomefrom aaanalysis.protein_engineering import SeqMut.
Fixed
Sequence bar in CPP-SHAP plots: with
seq_char_fill=True(the auto_font default),feature_map(),heatmap(), andprofile()drew each residue’s colored background as a glyph-sized text box, so narrow letters left hairline white gaps and the TMD/JMD band read as ragged against the heatmap grid. Each residue now gets a seamless full-width (one-column) colored cell, centered on its column, so the sequence band is gap-free and aligned.seq_char_fill=Falsekeeps the legacy glyph-box rendering unchanged.BH-adjusted p-values (#343):
p_val_fdr_bhindf_featnow follows canonical Benjamini–Hochberg — the reverse cumulative-minimum (monotonicity) step was missing, so the reported values could be non-monotone / slightly conservative in non-monotone regions. Only the reported column changes; feature selection and ranking (abs_auc/abs_mean_dif) are unaffected.run()withn_jobs > 1no longer crashes in non-interactive contexts (e.g.python -c, heredocs, some subprocess shells) where starting amultiprocessing.Managerfor the cross-process progress bar raisedEOFError/OSError. The Manager is now created best-effort: on failure CPP degrades to the thread-safe, single-process progress path and the run completes normally instead of aborting (previously the only workaround wasn_jobs=1). When the Manager is available, behavior and output are unchanged.CPP splits on free peptides / short parts (#338):
aap.find_featuresand thePattern/PeriodicPatternsplits were unusable on free peptides with no flanking context (the linear-epitope case).find_features(search="fast")and its Stage-3 simplify step ignored the requested / winning split configuration and always used the default (len_max=15,n_split_max=15), so any target region shorter than ~15 residues raised. Now:CPP auto-caps splits to the shortest part instead of raising. When a
df_partssequence part is too short for the requestedsplit_kws,CPPcaps theSegmentn_split_maxand drops thePattern/PeriodicPatternsplit types that cannot fit (Segmentis always kept), emits oneUserWarning, and stores the cappedsplit_kwsasself.split_kws(used by bothrun()andrun_num()). For parts long enough for the requested splits this is a no-op, so results for flanked inputs are byte-identical.``find_features`` handles free peptides end to end. The bounded
kwsdict now acceptslen_max(and actually honorsn_split_max). Passingkws={"n_jmd": 0}(no flanking context) switches the part sweep to TMD-only (the whole peptide is one part, instead of half-TMD composite fragments) and caps the swept ``n_split_max`` range to the shortest part length, deduped, with aUserWarning. The stagedbalanced/exhaustivesearches no longer hard-error on short parts. On normal (long-part) inputs the range cap is a no-op.
Version 1.0 (Stable Version)
v1.0.3 (2026-04-06)
Added
AAlogo: New class for amino acid logo visualization.AAlogoPlot: New plotting class for AAlogo visualizations.
Changed
Python Support: Dropped Python 3.9 (end-of-life) and added Python 3.13 and 3.14 support. Supported versions are now 3.10, 3.11, 3.12, 3.13, and 3.14.
Dependency Management: Migrated from
requirements.txtfiles to a singlepyproject.tomlas the source of truth for all dependencies. Introduced structured dependency extras:aaanalysis[pro],aaanalysis[docs], andaaanalysis[dev].Package Manager: Added full
uvsupport alongside existingpipandPoetrycompatibility.CI/CD: Updated all GitHub Actions workflows to reflect new Python version matrix and consolidated dependency installation via extras.
Other
Documentation: Updated
ReadTheDocsconfiguration to install dependencies directly frompyproject.tomlviaaaanalysis[docs]extra.Cleanup: Removed legacy
requirements.txt,docs/requirements_dev.txt, anddocs/requirements_wo_pro.txtfiles.
v1.0.2 (2025-06-17)
Improved
Faster CPP Pipeline: Major performance boost in
CPP.run()through optimized generation and filtering of part-split-scale combinations. Depending on the number of scales, runtime is now 3–5× faster on standard hardware.Feature Map Enhancement:
CPP.feature_map()now includes a top bar plot showing cumulative feature importance per residue, improving interpretability. This visualization is also included in the CPP profile output.
Fixed
fetch_alphafold(): Resolve download URLs through the AlphaFold API instead of a hardcoded file version. AlphaFold DB renamed its filesv4→v6, which had silently broken every fetch (all entries returnedalphafold_ok=False); the fetch now tracks the current version automatically. Added anetwork-marked live test (tests/integration/) so an upstream API/version change is caught instead of slipping past the mocked unit tests.General Bug Fixes: Minor fixes related to dependency resolution and edge-case behavior.
Documentation: Removed inconsistencies in documentation for selected functions and plotting options.
Other
Branding: Introduced updated logo and favicon (legacy version preserved under docs/source/_artwork/logos/legacy/).
Landing Page Visual: Added a main conceptual sketch to the documentation landing page illustrating the core CPP idea — comparing two sequence sets to derive their critical difference, the physicochemical signature.
v1.0.1 (2025-01-29)
Improved
Pro Feature Accessibility: Improved integration of aaanalysis[pro] features in IDEs. Clicking on a pro feature now directs users to its exact class implementation instead of the main
__init__.pyfile.Import Error Handling: Improved error handling for missing dependencies in the aaanalysis[pro] version. If dependencies are installed but errors occur during import, users now receive the original import error messages.
Fixed
Feature Map Plot: Resolved a potential mismatch in subcategory ordering between heatmap and bar plot in
aa.cpp_plot().featuremap(). Previously, subcategories with nearly identical names (e.g., “α-helix (C-term)” and “α-helix (C-term, out)”) could appear in an inconsistent order.General Bug Fixes: Minor bug fixes to improve overall stability and functionality.
Other
Dependencies: All dependencies have been updated to ensure compatibility with the latest versions, including full support for
numpy>=2.0.0.
v1.0.0 (2024-07-01)
Added
SequencePreprocessor: A utility data preprocessing class (data handling module).comp_seq_sim(): A function for computing pairwise sequence similarity (data handling module).filter_seq(): A function for redundancy-reduction of sequences (data handling module).options: Juxta Middle Domain (JMD) length can now be globally adjusted using the jmd_n/c_len options.
Changed
ShapModel: The ShapExplainer class has been renamed toShapModelfor consistency with theTreeModelclass and to avoid confusion with the ShapExplainer models from the SHAP package.Dependencies: Biopython is now a required dependency only for the aaanalysis[pro] version.
Module Renaming: The Perturbation module has been renamed to Protein Design module to better reflect its broad functionality.
Fixed
Multiprocessing: Now supported directly at the script level, outside of any functions or classes, in the top-level of the script (global namespace).
Version 0.1 (Beta Version)
v0.1.5 (2024-04-18)
Added
Code of Conduct: Introduced a Code of Conduct to foster a welcoming and inclusive community environment. We encourage all contributors to review the Code of Conduct to understand the expectations and responsibilities when participating in the project.
Changed
License Update: Transitioned the project license from MIT to BSD-3-Clause to better align with our project’s community engagement and protection goals. This change affects how the software can be used and redistributed.
Fixed
Multiprocessing: Replaced native
multiprocessingwith thejoblibmodule forCPPand internal feature matrix creation. This change prevents aRuntimeErrorthat occurred when the main function is not explicitly used.
Other
Dependencies: Update the
seaborndependency to version 0.13.2 or higher to resolve the legend argument error present in versions earlier than 0.13
v0.1.4 (2024-04-09)
Added
Installation Options: Introduced separate installation profiles for the core and professional versions. The core version has reduced dependencies to enhance installation robustness, installable using
pip install aaanalysis. The professional version, designed for advanced usage, includes packages required for our explainable AI module such as SHAP, installable usingpip install aaanalysis[pro].
Changed
API Improvements: General improvement of API for consistency and higher user-friendliness.
Fixed
General Issues: Fix of different check function related API issues.
Other
Python Dependency: Updated the Python version compatibility from <= 3.10 to <= 3.12.
v0.1.3 (2024-02-09)
Added
TreeModel: Wrapper class of tree-based models for Monte Carlo estimates of predictions and feature importance. See TreeModel.ShapExplainer: A wrapper for SHAP (SHapley Additive exPlanations) explainers to obtain Monte Carlo estimates for feature impact. See ShapExplainer.
NumericalFeature: Utility feature engineering class to process and filter numerical data structures. See NumericalFeature.Load_feature: Utility function to load feature sets for protein benchmarking datasets. See load_features.
Changed
API Improvements: General improvement of API for consistency and higher user-friendliness.
Fixed
Interface: Change of internal documentation decorator to hard-coded documentation for better IDE responsiveness.
General Issues: Fix of different check function related API issues.
v0.1.2 (2023-11-06)
Added
CPPPlot: Plotting class for CPP features. See CPPPlot.dPULearnPlot: Plotting class for results of negative identifications by dPULearn. See dPULearnPlot.AAclustPlot: Plotting class for AAclust clustering results. See AAclustPlot.Options: Set system-level settings by a dictionary-like interface (similar to pandas). See options.
Plotting functions: Extension of plotting utility functions.
Changed
API Improvements: General improvement of API.
Fixed
API Improvements: General improvement of API (Application Programming Interface).
Other
Python Dependency: Supports Python versions 3.9 and 3.10.
v0.1.1 (2023-09-11)
Test release of the first beta version.
v0.1.0 (2023-09-11)
First release of the beta version including CPP, dPULearn, and AAclust algorithms as well as the SequenceFeature utility class and data loading functions load_dataset and load_scales.