diff --git a/docs/source/_static/img/thumbs/tut8.png b/docs/source/_static/img/thumbs/tut8.png new file mode 100644 index 00000000..0f8249c2 Binary files /dev/null and b/docs/source/_static/img/thumbs/tut8.png differ diff --git a/docs/source/tutorials.rst b/docs/source/tutorials.rst index f1a67ea9..59152bb4 100755 --- a/docs/source/tutorials.rst +++ b/docs/source/tutorials.rst @@ -44,6 +44,7 @@ click it to open that tutorial. The full, section-ordered list follows below. ShapModel explanation
ShapModel
Evaluation and comparison
Evaluation
SeqOpt protein engineering
Protein engineering
+ Upstream bridge from FASTA to a scikit-learn pipeline
Upstream bridge
Data Handling @@ -119,4 +120,21 @@ mutation map and lineage. .. toctree:: :maxdepth: 1 - generated/tutorial7_protein_engineering \ No newline at end of file + generated/tutorial7_protein_engineering + +Interoperability +---------------- +Most analyses start with another tool's output. The **Upstream bridge** tutorial is the +recipe that carries a plain FASTA file, the one hand-off every tool can produce, all the way +to a fitted model: :func:`~aaanalysis.read_fasta` reads it, :meth:`~aaanalysis.SequenceFeature.get_df_parts` +adapts it to the part geometry CPP needs, and :class:`~aaanalysis.SequenceFeatureTransformer` +drops into a stock ``scikit-learn`` ``Pipeline`` so CPP feature selection runs *inside* +cross-validation instead of before it. This is the counterpart to the fixed-feature route, +where :meth:`~aaanalysis.SequenceFeature.feature_matrix` hands a plain numeric matrix to any +estimator. The two heavy representations, language model embeddings and AlphaFold channels, +have their own bridge in the **Embeddings & AlphaFold** tutorial above. + +.. toctree:: + :maxdepth: 1 + + generated/tutorial8_upstream_bridge \ No newline at end of file diff --git a/tutorials/tutorial8_upstream_bridge.ipynb b/tutorials/tutorial8_upstream_bridge.ipynb new file mode 100644 index 00000000..b87f7ab1 --- /dev/null +++ b/tutorials/tutorial8_upstream_bridge.ipynb @@ -0,0 +1,1081 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "c00-lede", + "metadata": {}, + "source": [ + "# Upstream bridge: from another tool's FASTA to a scikit-learn pipeline\n", + "\n", + "Most AAanalysis work starts somewhere else. A homology search, a motif scanner, a\n", + "proteomics filter or a colleague's export hands you a **FASTA file** plus a label per\n", + "record, and the question is how to get from there to a model. This tutorial is that\n", + "recipe, end to end, in three hops:\n", + "\n", + "1. **Read** the upstream file into a `df_seq` with `aa.read_fasta`.\n", + "2. **Adapt** the sequences into the part geometry CPP needs with `aa.SequenceFeature.get_df_parts`.\n", + "3. **Bridge** into a real `sklearn.pipeline.Pipeline` with `aa.SequenceFeatureTransformer`, so CPP feature selection happens *inside* cross-validation instead of before it." + ] + }, + { + "cell_type": "raw", + "id": "c01-box", + "metadata": { + "raw_mimetype": "text/restructuredtext" + }, + "source": [ + ".. admonition:: You will learn\n", + " :class: tip\n", + "\n", + " - **Tool**: :class:`~aaanalysis.SequenceFeatureTransformer` (with :func:`~aaanalysis.read_fasta` as the entry point)\n", + " - **Input**: a FASTA file written by an upstream tool, one label per record\n", + " - **Output**: a CPP feature matrix and a fitted ``sklearn.pipeline.Pipeline``\n", + " - **Best used for**: wiring another tool's sequence output into a leak-free scikit-learn workflow\n", + " - **Related protocol**: :doc:`P8: Prediction `\n", + " - **Related API**: :func:`~aaanalysis.read_fasta`, :func:`~aaanalysis.to_fasta`, :meth:`~aaanalysis.SequenceFeature.get_df_parts`, :class:`~aaanalysis.SequenceFeatureTransformer`" + ] + }, + { + "cell_type": "markdown", + "id": "c02-h1", + "metadata": {}, + "source": [ + "Everything below runs offline on the bundled `DOM_GSEC` benchmark and needs no extra\n", + "package: `scikit-learn` is already a core dependency. Only **one** bridge is covered here,\n", + "the FASTA hand-off, because it is the one every tool can produce. The two heavy\n", + "representations, protein language model embeddings and AlphaFold-derived channels, have\n", + "their own bridge in the *Embeddings & AlphaFold* tutorial.\n", + "\n", + "## 1. The hand-off: a FASTA file from an upstream tool\n", + "\n", + "To keep the notebook self-contained, the \"upstream tool\" is simulated: a bundled dataset is\n", + "written out with `aa.to_fasta`, which is also the writer you use in the other direction, to\n", + "hand AAanalysis results to the next tool in your chain. Substitute your own file here and\n", + "the rest of the notebook is unchanged." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "c03-write", + "metadata": { + "execution": { + "iopub.execute_input": "2026-09-18T17:17:16.402065Z", + "iopub.status.busy": "2026-09-18T17:17:16.401993Z", + "iopub.status.idle": "2026-09-18T17:17:17.721695Z", + "shell.execute_reply": "2026-09-18T17:17:17.721459Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + ">Q14802|0\n", + "MQKVTLGLLVFLAGFPVLDANDLEDKNSPFYYDWHSLQVGGLICAGVLCAMGIIIVMSAKCKCK ...\n", + ">Q86UE4|0\n", + "MAARSWQDELAQQAEEGSARLREMLSVGLGFLRTELGLDLGLEPKRYPGWVILVGTGALGLLLL ...\n" + ] + } + ], + "source": [ + "import os\n", + "import tempfile\n", + "\n", + "import numpy as np\n", + "import pandas as pd\n", + "import matplotlib.pyplot as plt\n", + "\n", + "import aaanalysis as aa\n", + "\n", + "aa.options[\"verbose\"] = False\n", + "\n", + "# Stand-in for the upstream tool: 40 gamma-secretase candidates written to a FASTA file,\n", + "# with the class label carried in the header (1 = substrate, 0 = non-substrate).\n", + "df_hits = aa.load_dataset(name=\"DOM_GSEC\", n=20)\n", + "folder_upstream = tempfile.mkdtemp()\n", + "file_hits = os.path.join(folder_upstream, \"upstream_hits.fasta\")\n", + "\n", + "aa.to_fasta(df_seq=df_hits[[\"entry\", \"sequence\", \"label\"]], file_path=file_hits,\n", + " col_id=\"entry\", col_seq=\"sequence\", sep=\"|\", col_db=None, cols_info=[\"label\"])\n", + "\n", + "for line in open(file_hits).read().splitlines()[:4]:\n", + " print(line if line.startswith(\">\") else line[:64] + \" ...\")" + ] + }, + { + "cell_type": "markdown", + "id": "c04-md", + "metadata": {}, + "source": [ + "The header convention is the only thing you have to match. `aa.read_fasta` splits each\n", + "header on `sep` and maps the pieces onto columns: `col_id` takes the first field, `col_db`\n", + "an optional leading database tag (as in `>sp|P12345|...`), and `cols_info` names whatever\n", + "follows. Here the single trailing field is the label." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "c05-read", + "metadata": { + "execution": { + "iopub.execute_input": "2026-09-18T17:17:17.722711Z", + "iopub.status.busy": "2026-09-18T17:17:17.722649Z", + "iopub.status.idle": "2026-09-18T17:17:17.747076Z", + "shell.execute_reply": "2026-09-18T17:17:17.746856Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "DataFrame shape: (40, 3)\n" + ] + }, + { + "data": { + "text/html": [ + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
 entrysequencelabel
1Q14802MQKVTLGLLVFLAGF...PGETPPLITPGSAQS0
2Q86UE4MAARSWQDELAQQAE...SPKQIKKKKKARRET0
3Q969W9MHRLMGVNSTAAAAA...AIWSKEKDKQKGHPL0
4P53801MAPGVARGPTPYWRL...GLFKEENPYARFENN0
5Q8IUW5MAPRALPGSAVLAAA...EVPATPVKRERSGTE0
6P01135MVPSAGQLALFALGI...LLKGRTACCHSETVV0
7O43914MGGLEPCSRLLLLPL...SDVYSDLNTQRPYYK0
8P05556MNLQPIFWIGLISSV...KSAVTTVVNPKYEGK0
9P16234MGTSHPAFLVLGCLL...DIGIDSSDLVEDSFL0
10P50895MEPPDAPAQARGAPR...SGGARGGSGGFGDEC0
\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "df_seq = aa.read_fasta(file_path=file_hits, col_id=\"entry\", col_seq=\"sequence\",\n", + " sep=\"|\", col_db=None, cols_info=[\"label\"])\n", + "\n", + "# Header fields arrive as strings; the label is the only one that has to be numeric.\n", + "df_seq[\"label\"] = df_seq[\"label\"].astype(int)\n", + "aa.display_df(df=df_seq, n_rows=10, show_shape=True)" + ] + }, + { + "cell_type": "markdown", + "id": "c06-h2", + "metadata": {}, + "source": [ + "## 2. The adapter: sequences into CPP parts\n", + "\n", + "CPP compares **parts** of a sequence, not whole sequences. `aa.SequenceFeature.get_df_parts`\n", + "is the adapter. When the upstream file carries domain boundaries (a `tmd_start` / `tmd_stop`\n", + "pair) it slices TMD, JMD-N and JMD-C. A plain FASTA has no such annotation, so it falls back\n", + "to a sequence-level geometry: the whole sequence as the target part plus its two flanks,\n", + "sized by `jmd_n_len` / `jmd_c_len`. That fallback is what makes an unannotated upstream file\n", + "usable at all." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "c07-parts", + "metadata": { + "execution": { + "iopub.execute_input": "2026-09-18T17:17:17.748024Z", + "iopub.status.busy": "2026-09-18T17:17:17.747966Z", + "iopub.status.idle": "2026-09-18T17:17:17.751598Z", + "shell.execute_reply": "2026-09-18T17:17:17.751397Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "parts: ['tmd', 'jmd_n_tmd_n', 'tmd_c_jmd_c']\n", + "DataFrame shape: (40, 3)\n" + ] + }, + { + "data": { + "text/html": [ + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
 tmdjmd_n_tmd_ntmd_c_jmd_c
entry   
Q14802FLAGFPVLDANDLED...CKFGQKSGHHPGETPMQKVTLGLLVFLAGF...FYYDWHSLQVGGLICAGVLCAMGIIIVMSA...PGETPPLITPGSAQS
Q86UE4AQQAEEGSARLREML...SQTKSETSWESPKQIMAARSWQDELAQQAE...ENLTVNGGGWNEKSVKLSSQISAGEEKWNS...SPKQIKKKKKARRET
Q969W9AAAAAGQPNVSCTCN...HTHIAPLESAAIWSKMHRLMGVNSTAAAAA...FHRFQPTYPYLQHEIDLPPTISLSDGEEPP...AIWSKEKDKQKGHPL
P53801PYWRLRLGGAALLLL...TRHDEIRKKYGLFKEMAPGVARGPTPYWRL...PPASLCKLSSARWGVCWVNFEALIITMSVV...GLFKEENPYARFENN
Q8IUW5VLAAAVFVGGAVSSP...SVSGAETVNGEVPATMAPRALPGSAVLAAA...HYIMKNEANADVLKAMVADNSLYDPESPVT...EVPATPVKRERSGTE
\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "sf = aa.SequenceFeature(verbose=False)\n", + "df_parts = sf.get_df_parts(df_seq=df_seq, list_parts=None, all_parts=False,\n", + " jmd_n_len=10, jmd_c_len=10, tmd_len=None,\n", + " remove_entries_with_gaps=False, replace_non_canonical_aa=False)\n", + "\n", + "print(\"parts:\", list(df_parts.columns))\n", + "aa.display_df(df=df_parts, n_rows=5, show_shape=True)" + ] + }, + { + "cell_type": "markdown", + "id": "c08-note", + "metadata": {}, + "source": [ + "You can stop here and hand `df_parts` to `aa.CPP` yourself, which is what the\n", + ":class:`~aaanalysis.CPP` tutorial does. The rest of this notebook takes the other route and\n", + "lets the pipeline own that step." + ] + }, + { + "cell_type": "markdown", + "id": "c09-h3", + "metadata": {}, + "source": [ + "## 3. The bridge: `SequenceFeatureTransformer` inside a real `Pipeline`\n", + "\n", + "`aa.SequenceFeatureTransformer` wraps the whole `get_df_parts` to `aa.CPP.run` to\n", + "`feature_matrix` chain behind the scikit-learn `fit` / `transform` API. It takes the\n", + "`df_seq` **itself** as `X`, which is what makes it a drop-in first step: everything\n", + "downstream is stock scikit-learn.\n", + "\n", + "That ordering is the point. Selecting CPP features once on the full labeled set and then\n", + "cross-validating the classifier lets every test fold influence which features exist, and\n", + "the score comes out optimistic. Inside a `Pipeline`, `fit` runs on the training fold only,\n", + "so each fold re-mines its own signature and the held-out proteins stay held out." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "c10-pipe", + "metadata": { + "execution": { + "iopub.execute_input": "2026-09-18T17:17:17.752461Z", + "iopub.status.busy": "2026-09-18T17:17:17.752379Z", + "iopub.status.idle": "2026-09-18T17:18:08.719430Z", + "shell.execute_reply": "2026-09-18T17:18:08.719204Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "balanced accuracy per fold: [0.5 0.75 0.875 0.875 0.625]\n", + "mean: 0.725\n" + ] + } + ], + "source": [ + "from sklearn.ensemble import RandomForestClassifier\n", + "from sklearn.model_selection import StratifiedKFold, cross_val_score\n", + "from sklearn.pipeline import Pipeline\n", + "from sklearn.preprocessing import StandardScaler\n", + "\n", + "# X is the sequence table (the label column is deliberately NOT part of X); y the labels.\n", + "X_seq = df_seq[[\"entry\", \"sequence\"]]\n", + "labels = df_seq[\"label\"].to_numpy()\n", + "\n", + "sft = aa.SequenceFeatureTransformer(\n", + " split_kws=aa.SequenceFeature.get_split_kws(split_types=[\"Segment\", \"Pattern\"]),\n", + " df_scales=aa.load_scales(name=\"scales\", top60_n=20),\n", + " n_filter=25,\n", + " label_test=1,\n", + " label_ref=0,\n", + " max_overlap=0.5,\n", + " max_cor=0.5,\n", + " simplify=False,\n", + " n_jobs=1,\n", + " random_state=0,\n", + " verbose=False)\n", + "\n", + "pipe = Pipeline([(\"sft\", sft),\n", + " (\"scaler\", StandardScaler()),\n", + " (\"clf\", RandomForestClassifier(n_estimators=100, random_state=0))])\n", + "\n", + "cv = StratifiedKFold(n_splits=5, shuffle=True, random_state=0)\n", + "scores = cross_val_score(pipe, X_seq, labels, cv=cv, scoring=\"balanced_accuracy\")\n", + "\n", + "print(\"balanced accuracy per fold:\", np.round(scores, 3))\n", + "print(f\"mean: {scores.mean():.3f}\")" + ] + }, + { + "cell_type": "markdown", + "id": "c11-caveat", + "metadata": {}, + "source": [ + "Forty proteins across five folds is a small-N estimate and the fold spread shows it. Read\n", + "the mean as a sanity check that the bridge carries signal, not as a performance claim. The\n", + "*P10: Validation* protocol covers how to report such a number honestly." + ] + }, + { + "cell_type": "markdown", + "id": "c12-h4", + "metadata": {}, + "source": [ + "## 4. Interpretability survives the bridge\n", + "\n", + "A wrapped estimator usually costs you the column names. This one does not:\n", + "`get_feature_names_out` returns the selected CPP feature ids, so every column of the matrix\n", + "the classifier saw is still a readable `PART-SPLIT-SCALE` statement, and the fitted\n", + "transformer keeps the full `df_feat` next to it." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "c13-fit", + "metadata": { + "execution": { + "iopub.execute_input": "2026-09-18T17:18:08.720441Z", + "iopub.status.busy": "2026-09-18T17:18:08.720371Z", + "iopub.status.idle": "2026-09-18T17:18:15.512013Z", + "shell.execute_reply": "2026-09-18T17:18:15.511801Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "selected features: 25\n", + "first three: ['JMD_N_TMD_N-Pattern(C,4,8,12)-TANS770102', 'TMD_C_JMD_C-Pattern(C,2,5,9,12)-OOBM850101', 'JMD_N_TMD_N-Pattern(C,1,5,8)-RICJ880117']\n", + "DataFrame shape: (25, 13)\n" + ] + }, + { + "data": { + "text/html": [ + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
 featurecategorysubcategoryscale_namescale_descriptionabs_aucabs_mean_difmean_difstd_teststd_refp_val_mann_whitneyp_val_fdr_bhpositions
1JMD_N_TMD_N-Pat...,12)-TANS770102Conformationα-helix (C-term, out)α-helix (C-terminal, outside)Normalized freq...Scheraga, 1977)0.3870000.1770000.1770000.1100000.0850000.0000280.0371559,13,17
2TMD_C_JMD_C-Pat...,12)-OOBM850101Structure-ActivityStabilityStability (extended-coil)Optimized beta-...e et al., 1985)0.3700000.128000-0.1280000.0830000.0790000.0000620.03715529,32,36,39
3JMD_N_TMD_N-Pat...5,8)-RICJ880117ConformationUnclassified (Conformation)α-helix (C-terminal, outside)Relative prefer...chardson, 1988)0.3630000.1170000.1170000.0820000.0730000.0000880.03715513,16,20
4JMD_N_TMD_N-Pat...5,8)-FASG760105PolarityUnclassified (Polarity)pK-CpK-C (Fasman, 1976)0.3550000.253000-0.2530000.1880000.1690000.0001220.03715513,16
5JMD_N_TMD_N-Seg...,12)-DAYM780201OthersMutabilityMutabilityRelative mutabi... et al., 1978b)0.3550000.0870000.0870000.0470000.0730000.0001220.0371552,3
6JMD_N_TMD_N-Seg...,12)-QIAN880128ConformationCoil (N-term)Coil (N-terminal)Weights for coi...ejnowski, 1988)0.3550000.083000-0.0830000.0370000.0670000.0001220.0371552,3
7TMD_C_JMD_C-Pat...,12)-OOBM850104PolarityHydrophilicityNon-bonded energy per atomOptimized avera...e et al., 1985)0.3530000.1230000.1230000.0890000.0840000.0001370.03715529,32,36,40
8TMD_C_JMD_C-Pat...5,9)-WILM950103PolarityHydrophobicity (interface)Hydrophobicity (interface)Hydrophobicity ...e et al., 1995)0.3440000.1050000.1050000.0790000.0640000.0002000.04071032,36,39
9TMD_C_JMD_C-Pat...4,7)-TANS770102Conformationα-helix (C-term, out)α-helix (C-terminal, outside)Normalized freq...Scheraga, 1977)0.3350000.1710000.1710000.1270000.1300000.0002890.04368221,24,27
10TMD_C_JMD_C-Pat...5,9)-SUEM840102Structure-ActivityUnclassified (S...cture-Activity)Stability (extended-coil)Zimm-Bragg para...i et al., 1984)0.3320000.1830000.1830000.1450000.1170000.0003210.04675332,36,40
\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "pipe.fit(X_seq, labels)\n", + "sft_fitted = pipe.named_steps[\"sft\"]\n", + "\n", + "feature_names = sft_fitted.get_feature_names_out(input_features=None)\n", + "print(\"selected features:\", len(feature_names))\n", + "print(\"first three:\", list(feature_names[:3]))\n", + "\n", + "aa.display_df(df=sft_fitted.df_feat_, n_rows=10, show_shape=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "c14-plot", + "metadata": { + "execution": { + "iopub.execute_input": "2026-09-18T17:18:15.512970Z", + "iopub.status.busy": "2026-09-18T17:18:15.512894Z", + "iopub.status.idle": "2026-09-18T17:18:15.603492Z", + "shell.execute_reply": "2026-09-18T17:18:15.603257Z" + } + }, + "outputs": [ + { + "data": { + "image/png": "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Lbvo125ulRvugjBAYznC2Ls63vYhIp6W9EIIIYTIevJE4oUZswnvw1BiYWWPII9ueo/LCGGcM7vAt8yKLSxTmAjuGLBSCccEPSwnO9PEo3///lYUc5dAZA0MCplkWrHPEFOoYi01sxBC5FBWDE5tH03v3/zZs2fbuWYi/eQI1UjEL8hmgh+ZSGlmHpcRwjhndkE0mig6nt94dxscTDBNJIyzM40frAzC3Q2JcCGEEELkNHJERFwIcWijiLgQQhwaKCKes5AhVAghhBBCiBCQEBdCCCGEECIEJMSFEEIIIYQIAQlxIYQQQgghQkBCXAghhBBCiBCQEBdCCCGEECK3riMuhDg8mNi/pR7uIIQQQiSJIuJCCCGEEEKEgIS4EEIIIYQQISAhLoQQQgghRAhIiAshhBBCCBECEuJCCCGEEEKEgIS4EEIIIYQQIaDlC4UQmUan52eaQhXXqEVFjmTF4E5hF0EIIVKgiLgQQgghhBAhICEuhBBCCCFECEiICyGEEEIIEQIS4kIIIYQQQoSAhLgQQgghhBAhICEuhBBCCCFECEiICyGEEEIIEQI5dh3xLVu2mLx585rixYubnTt3mn///deUL1/eFCxYMJpmz549ZsOGDaZixYpm3759ZtOmTXY7x5UqVcoULVo04Xl27dpltm/fbsqVKxfdduDAgWi+QaxZs8ami+XII480kUgkx5V379699rgyZcqYnMbBgwdtGzg2b95s2yNPnjz289atW02hQoXsKx60eWz9Yo/dtm2bfe+9LrHtm8x12b9/v1m3bp05+uij7ed//vnHlC5d2hQpUiRFutWrV9vtlI3/jzjiiBT15jj6DPnR572QlmNcuehXsWVhO9e/WLFiqbaTv/d88dID5+f75r0WQgghhMg6cuwv7gMPPGBeeukl+/6jjz4yxxxzjHnttddSpHnuuefs9qVLl5qJEyeaWrVqmaZNm5omTZpYcXPeeeelEjexcFyVKlXMkiVLotv++usvm088OnXqZNM0atQoel5e06dPz1HlRbzdeuutpmzZsua4444zFSpUMHfeeafJKfz+++/mmmuuiX5ev369ue6666wI532zZs1sfRGkt912W2A+c+fONSeeeGKKfPyOpa0GDhwYmE+y12XkyJGmcuXKZs6cOfbz4MGDzcUXX5wizbvvvmvOOecc89tvv9nrznXw8vnnn9vtnHPEiBHRPsTr2GOPNffcc49Nd/PNN9uBFwO7q666yl5TeOSRR+x15Zry3g24LrjgApuW7V27drXbgtJ7B5YNGjSw7SaEEEKIXC7EY2ncuLEZO3Zsim1TpkwxNWrUiH5u3bq1+fvvv22UcePGjTbyecMNNyTMG7GWTDovCDDO9frrr0fPy6tjx445qrxffvmlPe+qVausyFq0aJH57rvvzA8//BBNwx0HIvSx/Pfff/Z/IsTsJ6K+Y8cOK+yINDuI9sYSm6c7ligt7x3z5s2z4tjlcffdd5sbb7zRvh8+fLhp3769jZBT/g8++CBFuR0M2Lp06WLzdwQdW7duXSuqZ82aFdhmyVwXhDOieOjQofbz448/buvy8ccfR9uEAc9bb71lChQoYMX91KlTU9xFGTNmjO0n0L9//2gf+vrrr61Av//+++31+uSTT2xknQj8N998Y6/fggULbN9bsWKFrd8777xjtyHqCxcubM9P2bmGlCEoPXz66aemZcuWNr0QQgghso9DRojXrl3bioq1a9faz0SEESuIHD+4Jf/8889bMYwojAeRwDp16pi33377sCsvYpjoMrYYwLqB0CPqik2he/fu1l5BpPS+++6zaRCvzZs3t4L/pJNOshHh+fPnW9GJSK5WrZq1wQwbNsy0a9fOVK1a1aZDoAflybFEZzmO7b1797bbBwwYYGbMmGHuuusuO1BAaJ522ml2H0L2wQcftOV3EX3vAMBBxPmLL75IsS3esRdeeKF55plnErZd0HXhWjJ4QHwj8LG7kA6hi2BHBN90003m+uuvt9cKEPMnn3yyrStwPRDd1atXT3VO7ghQdtqK64V4RzRTT44jos0Aq3PnzjZSTtSeKPj48ePtgIR+QT9DkHNdqHdQemCAwnui6EIIIYTIPg4ZIQ4IiQ8//NC+Hz16tOnWrVvc9EcddZT1whIBTMSgQYPMs88+6xvdPZTLS1SYKD3CHfGN4MUO4qwyCD1E9uzZs200FZGOzQLhykDijTfesPsc33//vT0eC861115rLUQId8QiUeagPJ39YdmyZTa6O3nyZPse0UgZEfWIRRchjoU8SE/kNpaXX345rj8+9ljaAVtIssReF6LhCFkE7amnnmqjy9CmTRtrRWnRooW1H8Vaabj+7i7JpEmTzFlnneVbVtrpoosusp8R3fSjtm3b2kj96aefbmrWrGmj45UqVUpRRrZ5+fPPP+35OG+89I8++qi9U5AIBgGIer+X9y6HEEIIIQ5BIU5EFetCELFCBnGSCCbBlSxZMmE6Jqnde++9cX3IaSWM8iKunMUBcUxEmMgt2//3v//Zz0ScsTcQfcb2wGdEHhHpP/74w27HdsGkPTzwRMcdCM0SJUpYYY/gZl/+/Pmt9YLIcFCeQPScciNgsejEireVK1faKHwsRLuvvvpqM27cuFSTIRPhdyzn504BAjK2vRJdF/onVg/ENsdQRwYRjieffNIsX77cDg7y5cuXIo8OHTrYAQDnYWDGnYNYXnnlFRtNd4waNcr88ssv1jaCRYg7LK+++qq9Nt7vCuXjOjiwtJx77rl2ngJ3LBKlTwb6EW3g92rVqlWa8hJCCCFEDls1hUglwpWIH2IldmULbvMjnKZNm2Zv6SdaRePnn3+2eRD9SwasE0zCcxHcjBJGeZkw6CLeiGJEMwKUF2KJF2IcSwX2hSFDhphevXrZ9ETAEWd4l7GYOLzvvXXws9kE5Yk1BauEgzK4SYcOv5VMmPBIlB1/NdaetBDvWM7N+WhDb3slui4IaVao8XrGiWBj76D/0t60kXdVGwf2FSaUMijD2sLgJXYgSv6Ica+gJtLuVj8hOs7EVCwnXp873m83iPn222/t3Qr6BhNOATEelD5ZuJsSNNEVf7zEuBBCCHEIC/GGDRtawYaYZIIhgi4WhAjRWj+Pr/PdEvnDikBkMXalikS88MILNsqZWWR3eWO90tgOsJFgIWGVD2wk2Eb69Olj7QisnkF0GrHdt29fa6Uhksp2xCTi7ccff4wuJZgIVpPxyzMIRDrCFjGLHYZIvQOrChYcVqHh/LQVUXjEPhHieAOWoGNZ/o+oMn5oBgax7YXojnddsKVwF4J2ddBfiYonWmnH3SVhYubll1+eah+Rbyw2LJnoQNxedtll1lbD3QQi7QhiPrOqCp5w2uO9996zApxoPLYWIu7kRT0YHBCN90ufFuItIem3HKIQQgghDiEhjrjBRtCjRw8rGM4++2y7nWggdgLAm0vU3O1DbCAsEFhMokMMYQlg+5VXXmlFTzw4zuUNRAmZQIhQSQYizbHRz5xUXiYtcr7bb7/dRucRoJyHciE0EcFETxGrCGgirdhREMZMasROg2+b8yIEXRQbq4PXc0yZELYITL88EbjeCLhbY53BF2L8jjvusJYLJoNiG6HMRIaxj3i91Aw8sMVgkcED7YgtT9Cx9CvEd5BfP951YVUWotGxgyralvZkP9eeiape2wf1dB52yo0gdrYU2s2tDc4AAcuLF6LhTHhF/HOX6NJLL436x9988007qZOBA3Ujwo5dietKeRxMGkW8+6X3wsAm1k4jhBBCiKwjTyTWH3AY4n1ISyyIpqBob3qPyyhhnddB1BxRSdcgQo0NgwmWQQ/ByUweeughGxnv2bNnYBq86AhSt1RgWsGrzvKG3CEQmQPLeTLgqthniClUMaXAFyKnsGJwp7CLIMRh9TefRRmCFlkQh2BEPKvAI8yScH4sXLjQ3rrPzOMySljndWBdIbKK+MZbjZ88O0Q4EBnv16+fvSsSNOBgkicrraQHVn1hFRmJcCGEEEKETa6IiAshshZFxMWhgCLiQmQOiogfpssXCiGEEEIIkVuQEBdCCCGEECIEJMSFEEIIIYQIAQlxIYQQQgghQkBCXAghhBBCiBCQEBdCCCGEECIEcsU64kKI7GFi/5Z6uIMQQgiRJIqICyGEEEIIEQIS4kIIIYQQQoSAhLgQQgghhBAhICEuhBBCCCFECEiICyGEEEIIEQIS4kIIIYQQQoSAli8UQmQanZ6faQpVXKMWFdnGisGd1NpCiEMWRcSFEEIIIYQIAQlxIYQQQgghQkBCXAghhBBCiBCQEBdCCCGEECIEJMSFEEIIIYQIAQlxIYQQQgghQkBCXAghhBBCiBA4ZNYR//vvv82RRx5pihQpYjZu3Gj+++8/U6tWrRRpNm/ebLdXr17dbNq0yX6GfPnymQoVKpiiRYsmPA/HRSIRU7Zs2ei27du3mx07dtg8/Ni/f79ZsWKF7z7K4sqVE8rrPU/evHlNmTJlTKlSpRKehzrmz58/1fvMYO3ataZixYrRz9Rn/fr1tv7FixcPPG7p0qXR97QZ7RgLeZE/7VOgQAHf88VC+9BOXgoVKmSOOeaY6Odly5aZKlWqRPN07N2715b9qKOOsmWKZc+ePXY/5aEvxztniRIlTPny5e37ffv22TTus2PLli3mwIED9jrGwvekdOnSKcrhl57ybN26NfqZsh9xxBGB7SOEEEKIXBYR7969u/nxxx/t+wcffNDUrl3b/PTTTynSXH755ebEE0+07x9//HFzyimnmLPPPtucccYZply5cua6664zBw8ejHsejjv55JPNzp07o9s+/fRTc9NNNwUes27dOnseXhzrzstrw4YNOaq83vO0bdvWite+fftawRrEmDFjzHPPPZfqfWbw1VdfmVdffTX6+cMPPzQ1atQwDRs2NJUqVTKdOnWKDhy8rFy50jRo0CDazj179kyV5s8//zR16tQxjRs3tsJ73Lhxdvv06dNTnDOWl156ybapy5vXNddcE93/3Xff2ev59ttvpzju2WeftYOf0047zQrmbt262QERUIfevXvbQQ/tjxAmTwQ2vP/++ynO16hRI/PQQw/ZfS+++KI9rm7duvaaIebh3nvvtYODqlWrmnvuuSdFWf766y/bhvQ/R1D6iy++2Jx55pnRc3///fdxrpgQQgghcp0Qj6VJkyZm7NixKSJ9sRHF/v3726gp0erly5dbgfH8888nzLtYsWJWPCfL0Ucfbc/DC3HlzsvLRV5zUnndeYjqrl692sycOdN8/vnnvhFSRN8PP/xgo8gMONx7Ivne9ETJHewnMuzqx2fyIVK/bdu2aDrE/x133GEGDhxoP1Pffv36mXfffdcew/GIca8IdsydO9ecc8450XaOHeQ4AcsAbs2aNeaDDz4wt99+u91+4YUXmuHDh9trEMQVV1wRzZvXZ599Ft03YsQIc+2115phw4ZFt9GOjz32mPn111/NqlWrbPmJRn/00Ud2PwOFPHny2O2Uh4HEb7/9Fh3UMOjynqty5cr2mi5cuNA8+uijNl/amb72xRdfmPnz59t2oq8gujnPvHnzbF68b9WqVYprFC89/7Pfnf+ss84KbBchhBBCZB6HrBA/99xzzfjx46OfP/nkEyvMgiBC+fDDD5u33norYd6XXnqp+fnnn80vv/xy2JcX+8dJJ51ko8fkQTSaQQMC+KmnnjJLliwxI0eOtOIT4eneE7lGtBGVdhHnd955x+Z5ww03mA4dOlgrzrRp0+znzp0727yxZDzxxBM23aRJk8yxxx5rBxLwwgsv2EECEWUoWLCgefrpp60o9hPi9erVM//++6/ZvXu3b90434IFC2y7MICoWbOm3Y4gJvL7xhtvBLYLItYrxHft2mW3c+fh448/tuIY6wfl8A4s3OADy8rrr79uLrnkEityEdKcr2TJktHry353R8QLgxHy564Iopzry/Ug7zfffNPeJfjyyy/N+eefH7UWXXDBBWbC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5ttvvzVt27a1be/44osvzBlnnBG91itXrjTLly831apVM1WrVrVp//zzT1sHL0cffbQ54ogjfLc3aNAg2rb0jSZNmqQ4J/z666/m2GOPNQULFoxu80tPn6LPUCfql6ivCCGEEOIwEOKvvfaa+ffff61A++uvv6Ji69577zUrVqwwl112mXn44YfN3XffHT1myJAh5n//+58VGbz69etnj0NErFq1yv4/ZcoUK3Li8dlnn5krrrjCipr8+fNbYfTee++ZM888M6myDx061Iq+O++800ybNi3HlHXmzJnR88DmzZutEEUgHnPMMb75//zzz7acY8eOTfE+M/jjjz/Myy+/bF599VVbth49ephvvvnGClg3cOjTp4+93n589NFHtj6kC4L+c/rpp9v2vvDCC1PsmzRpkvnqq6+in3lPvzvrrLPM9ddfb0aPHp3mvokQ57qdf/75tq1uvvlmu4907du3t8deeeWV0bw6d+5s1q5dawdFN954o23bunXr2johksnrxx9/NCNHjowew3Xgmjdq1Mh3O+elrnxGUCOs33///RSDF/oHA0Y3OPFLT/9goEg5EOS8uE6lS5cObG8hhBBCHAZCHDEJn3zyiRW2n3/+eXQfwozI6YcffphC3CIoa9asGf2MQPIed/vtt5urr77aipsgEMG9e/c248aNsyIEJk+ebIUK+4oUKZLmuuSkssae56qrrjLPP/+8efLJJ83evXvtoIBo78knn2yFPQOJ1atX22ip9z0ikOgpUWXOU69evei1IbqLSK1cubKNahNhRsSxjaiqi8Ledttt5oknnkhRtoEDB1qxlyjyilBGtJNvEJFIxArTcuXK+e5noMQLELTUl/ZEjJYvX94Ocjp27JimvgkjRoww99xzjxk2bFhUiEOVKlXMK6+8Ys477zybvxei3vQR/nd3NAYPHmy+/vprc9FFF9kXIMq5Zg888IBN57eddvntt9/MwoULbV3oGzNmzLB3Fp577jnz4osv2rZxBKWnH9Aero3oV2+++aYZMGBA3GsjhBBCiMPcI37UUUdZAYidAYjmYcuIvQXvhYglUU/sFUEgsoiIOmELRDIRJt7b+IdLWevUqWNtMkTSa9eubYUjA4AWLVrY/R9//LFZtmyZmThxYor3HINYJ4rbs2dP07VrVyvuPvjgA9OhQwcrCknP506dOllBe8kll9iy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xaZDhw6mUKFC0TRs+/333815551n/+cF+fLlM0cddZQ56aSTTJ48eeKeh2O2b99umjRpEt22bt06s3z5ctO0aVPfY/bu3Ws+++wz331nnXWWWbVqVY4pr/c8efPmNWXKlDGnnXaafR+PjRs3mrJly6Z6nxn88MMPKcr633//mTlz5ti2Ovnkk03BggXjHv/999+b+vXrm+LFi6fa9++//9q8jjnmGFOnTp3APCKRiPnxxx9TtRn9jvaJR2ya6dOnmy1btkQ/t23b1mzYsMEUKVLE9l8/Pv/8c7N79+5U20855RRTqVIlc+DAAfPpp5+a1q1bm5IlS9p9XPcvv/zSnHPOOSmuH+noa/Qj18/+/PNPU61aNXPsscfatGzje+SlSpUqplixYr7bGzduHG2jffv2mebNm6fqM7RzvXr1on08KP3BgwftNadOzZo1M/nz6zlfQgghRHaQ7l/c+++/39x8881WdLz11lvmqaeeMh988IHp3LlzNM0dd9xhJkyYYPbv329GjRpl3n33XSsM+Lxo0SIrHqdMmRIVMn5w3NNPP23FCOINZs2aZYYOHWoFjh979uwxb775pn2PwEF4cF5ASOak8nrPA3///bct77fffmtFmB8jR440S5cuNY888kiK95nBuHHjbH5OAD/zzDPm0UcfNSeeeKLZunWrWb9+vR3kuPLG8tNPP5nTTz/dzJ0714pxL7/88os588wzTcOGDW179uvXz9x7772p8kAw0r9mzpxpvvrqq+j29957z/Y5yhCEX5ru3bubli1bRj9Tt6JFi5rrrrvO9gE/Ro8ebTZv3mzWrFljVqxYYQUqINwR4gj1nj17mkGDBplbbrkleu3OP/988/LLL9u6OS688EKzdu1aez2vuuoqM3nyZNs2DNAQ+9OmTTPz58+3/cDB9Sct7e63HSHetWtX88cff9jBIYOajz76KMVgqF27dmbJkiWmYsWKdptfevo214TBFgKcwcLXX39tChcuHNjGQgghhMgcMi301apVKzNmzJiosEXEICi9IFIQwED0DSGD4Hruuefi5k0U8sYbbzSffPJJUmUhEuvSIiIRGe68ObG83vMAohGBeNlll9lyIdKIaiIgd+zYYYXStm3bzOzZs6Pviaofd9xxNvJLJJQIPp/BfWZQ0qBBAyssGSRwZ4C7B5QXAUYdH3zwQSviYOrUqebZ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nj83sn//fvPaa6+ZSZMmmb/++stUrFjRdOvWzfTt29fky5cvS/Pas2ePOfHEE83BgwcD83zvvfdM48aN01W33ML8+fPNc889ZxYuXGjy5s1rTjnlFNO/f39To0aNDOX7zjvvmEcffdRMmTLFVKlSJdvPn1vYtWuXeeGFF8z06dPN2rVrbVv36tXL9OzZM0P57tixw7Rt29a0a9fOPPjgg75p+J6SJh7Tpk0zRx99dIbKIrKYiBAiVzJ+/PhIgQIFIvwZ8L4KFiwYee+997I8r8w8f25k+/btkVNPPTVV+/Fq3bp1ZPfu3Vma15w5c3zTe18zZ87M5FofXrz66quRvHnzpmq3YsWKRb744ot05/vbb79FSpcubfNasmRJtp8/t7B+/frIscce69v3e/ToETlw4EC68j148GCkd+/eNp9rrrkmMB1/QxN9B5cvX56BGorsQEJciFzIypUrI0WLFrV/qC+77LLId999Z0XThRdeaLcVKlQo8ueff2ZZXpl5/txKnz59bFtVrVo1MmrUqMi8efMiw4YNi5QpU8ZuHzBgQJbmNXLkSLuvV69ekUWLFvm+du7cmcm1Pnz4+eefI/ny5bNtOHDgwMisWbMi06ZNi7Rv395uo+03b96c5ny5dpUqVYoKsSAhnlXnz02ceeaZtq3q168fGTduXGTu3LmRJ598Mvq37emnn05znnv37o1ceeWV0esXT4gPGjQoev2CvoPkJ3I2EuJC5EJuvPFG+we8a9euqfZ1797d7uvXr1+W5ZWZ58+NLFu2zIoo7ij88ccfKfYxqMmTJ48dzGzatCnL8rrlllvsdRo+fHgm1Sp30aVLF9t+/fv3T7F93759kRYtWth9CK1k2b9/f+SVV16JFClSxB7LdYsnxDP7/LmNb7/91rZRqVKlbGTcywcffGD3lStXzrZnsiCcTzvttBTXL54Q79mzp00zZcqUDNVFhIuEuBC5DG57li1b1v4B//7771PtJ6rDvvLly9u0mZ1XZp4/t/L444/bNurWrVvcSN2bb76ZZXm1a9fObscGIdLG1q1bI/nz57ftt2rVqlT7J0yYYPc1atQo6TybNWsWtXY999xz9u5GkBDPivPnNq6//nrbRjfddJPv/uOOO87uT9biM3r06Og1YSB07733JhTidevWtYJddy4ObbRqihC5jBUrVpiNGzeaokWL2olZ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lipVKjAdbcx3hUeg8yTGeCxbtsyucV2zZs2E1zHZ84v4T9pkKUO+N/FWC3LXpWLFinHbmidiMqGdJ3TyvUrEunXrrOeffDW35tBCQlwIIYQQQogQ0KopQgghhBBChICEuBBCCCGEECEgIS6EEEIIIUQISIgLIYQQQggRAhLiQgghhBBChICEuBBCCCGEECEgIS6EEEIIIUQISIgLIYQQQggRAvnDOKkQQoTNjBkz7BPugsifP7990mD16tXt0+0OFb744gv7f9OmTU2xYsXMocr69evtUwgLFSpkjjnmmFz91FWedDp79mzbJ1u3bh12cYQQmYierCmEyJXweGke554Mp556qnnqqadMixYtTE4nT5489v+5c+eaRo0amUMNBkfXXHONGTlypDl48KDdRj2oz+HCxIkT7eDutNNOSyr9V199Zc444wxzxBFH2Meo50bS2mZCHCooIi6EyNXUqVPHVK5cOdX2vXv3mhUrVpi//vrL/Pjjj6ZNmzZm6tSpplWrVqGUM7cwdOhQM2LECPu+Zs2a5qijjjqsxNdll11mBxljx45N+hgE6JlnnmmKFCliciPpaTMhDhUkxIUQuZobbrjBvoKYPn266datm7UHXH/99ebXX3/N1vLlNoj+wnnnnWfGjRtnDje++eabNB/TsGHDqOUoN5KeNhPiUEGTNYUQIg5YAp555hn7/rfffjPz589Xe2Uh27Zti3rchRDicEcRcSGESIDXjsIEQiKUfqxZs8b8/fffZvfu3aZMmTLW9sIEu1j+/fdfM2fOHFO2bNmoj3v16tXWCsPkxHr16iW0IeCf/vPPP826devshNJKlSolfR3Xrl1rj8VPXqNGDVOhQgXfdK6cTJR0df7nn3/M8uXLo/XLm/f/x3MikYj5448/zIYNG0yVKlVM1apVky7TggULbF02btxoP9MWRIHJH1tQeuuwadMm6y8vX768OeGEE+znRYsW2ban/M5T7+D8XOMDBw7YfCtWrJjUxNKlS5fa+nOeWrVqpcp35cqVZsmSJWbXrl3R+jJPgTaqXbt2uiZrZsX1cXlihznppJOi14L+iU2oWrVqKfIMIjOuT+HChW27Jttm2fn9c2WnjsxrwEYVVMeM9i9xmBMRQohcSMmSJSP8CXzhhRcSpv3mm29sWl6fffZZin0HDx6MDB06NHLcccdF07hX8eLFIzfffHNk165dKY6ZOnWq3d++ffvITz/9FDn11FNTHFe0aNHITTfdFNmzZ49veYYPHx6pVq1aNH2ePHkiXbt2jWzYsCG6be7cuamOmzRpUqRJkyapysn5v/zyy1TpXTk7deoU+fvvvyMdO3a053LH1a5dO/LDDz/YtDNmzIgce+yxKfJt1apVZPXq1ZFk6NatW6py8cqXL1+G6kB69p9//vmRUaNGRQoXLhw9pl+/ftF0XIfWrVunqB+vpk2bRmbOnOlb5u+++87ujy1LmTJlInfccUdk9+7d0bSPP/64b/1uueWWhG0zffp0m/aII47I8uvj8mQfeZ5xxhkpjiFP2jGIzLw+sd8LvzYL4/v3/fffR84666xUfYU2++WXX3yPSU//ErkDCXEhRK4kWSG+d+/eyJlnnmnTIhL+/fffFPuvu+666I9q5cqVI82bN4+ceOKJkWLFikW3X3TRRb5CoGrVqvZHn/fHHHNM5LTTTouULl06etyVV16ZqjwPPPBACsHXokWLSPXq1e3nk046KVCIP/vss9F9hQoVsuKDF+/Zljdv3shrr73mW07EghP+9erVs+cpWLBgtAzjx4+PFChQIFKkSBG7zyv4ECfJ8NBDD9l2Jj8n+Pjcrl27DNXBCT2EGumOPPLISLNmzez1nzZtmk3z8ccfR+tDmgYNGthrUaJECbstf/78kdGjR6fId8GCBVHRSLqTTz45cvrpp9tyuzJefPHF0fTvv/++rQ9txD7Owedhw4ZlWIhn5vVxeZLOidsaNWrYfoawdcdxLWLJ7Otzzz33JGyz7P7+vffee7Yt2U8bc915ub5QtmzZyOLFi1Mck57+JXIPEuJCiFwtxG+44Qb7w+x9TZkyJfLhhx9GBg0alCLSdu+996bIY9asWdGo7ZgxY1Ls27p1a+Syyy6L7t+4cWMqIcCrXLlyKaLsRO969OgR/YH2Cn/ENXmxj0ifN+LK+Z1giRXic+bMiUbiyNtbFqLoRNPd+ebPn+9bzgoVKtgIsGP27NlRQULeRGPXr18f3f/0009Hj122bFnS18UNep588skU29NbByf0eCHwtm3bZrfv2LHDRlOJCDuBeeGFF0bWrVuX4lrcdddd0SjpX3/9Fd3Xt29fu71z586pIq5EOKkHEdfYfTVr1rTHjR07Nuk2SSTEM/P6ePNEXDKAcNB2vXv3jgrKJUuWZPn1iddm2f39o6848XzuueemaE/eM6hxdyi8x6Snf4ncg4S4ECJXC/FkXvyQDxw4MHLgwIEUebz55ptWcBG584Mff5fHzz//7CsE3n333VTHYQlw+7/99tvo9muuucZua9mype/5nnnmGV8h3qtXL7uNSOG+fft8o/4NGza0aS655BLfcr711lupjjvnnHOiEWGEjxfO46KEn3/+eSSjQjy9dfAKPQZYsdx9993RCLBfvtC2bVubBtHkwJrAtgcffDCSFrJKiGfW9fHm+eKLL6bKk+Pq169v9992221Zfn3itVl2f/+cvYi7D7EDLFixYoXtF2effXZ0f3r7l8g9aLKmECJX411HnAlUTL5atWqV/cykrQsvvND07NnTd3JYnz597CsIHr7CZLH9+/ebPXv2+Kbp1KlTqm1HH320KVq0qNm5c6fZsWNHdDvrmMMll1zim9cVV1xhbr311uiDcBzTpk2z/1999dW+k9cKFChgrr32WtOvX7/AZfI6duyYapub7NesWTNTvHjxFPs4z5FHHmknwTF5LqNkRh381iOfMmWK/f/444+PLp0YC5Pq4Msvv4xua9KkiT3PQw89ZH766SfTvn17c/rpp9tJk7ETNbODzL4+9L8rr7wy1XaOo8/fdtttZvLkyeaJJ57I0usTj+z+/rm+wt8EJpL6tbf7jma0f4ncg4S4ECJXE7uOOCL29ddft9sWL15sBUyiVS34weYHd+HChVbI8+I9q4B4842FH/uSJUv65smqDeTL4MDBw4Xc4MGPEiVK2NUwWP3B+2AiV4769esH1sHtY+UJVoFAODl4j2iLxQkuv33e/dx9zQiZUYdixYrZJ1PGwrWCd955x77iwconjttvv918+umndl35zz77zL6A1T8Qxb1797YP4ckOsuL61K1b164g4geiEtyANSuvTzJk1/ePFVm89U+G9PYvkXuQEBdCCA8szUZUjx9pIs8333yzKViwoI3kxYKAGTx4sHnqqafskmh+ETLESpAQ9QqRRCBceAHlCSJWzHijnX5RPIc3z9jy0hbxyOoIcGbUIUhUIraASDbL2cXD2w4s7zdr1izz6quvmlGjRtmnryL2WMrwzTfftK8LLrjAvP/++yZfvnwmK8mK6xNPFLt2dlHmrLw+8cjO75+LsCf6/mVW/xK5BwlxIYTwgYgmT/QbNmyYjY6zRnDXrl1TpHnyySfN3Xffbd+fcsopNgLKGtLcaiZqxvrOfrfp0wOigbWRERys0RyEW4fbQUSfYxHxrDEdBBYFYJ3mtAiN7CAr64CgJkKLxWHAgAFpKheis3///vbFdZkxY4aZOXOmfSIokVAeyX7uuecGWolyMrH9yAvtBawrHmYfy87vn7evMNgK4ocffrCCnTXRuTuSkf4lcgd6sqYQQgTw9NNP2wd1EOnkhzT21vGLL75o/7/uuutsRPSxxx4zl19+uX3oCsL9999/j0bjvLe408vJJ5+cwncaCw9r8d6Od9FQ99CSSZMmBebt9uGLz2lkZR0aN25s///8888D07iHCyGynBWDz7zcXQoGSV26dLFPYeW64yEHd8yhBnUIGvA5H7TzdIfVx7L7++fqyIDLDwQ4D/9q27ZtdLCSnv4lchcS4kIIEef2/BtvvGGFBj+y11xzTYr9LjLm94RCnoaIxcURNFksLVx88cX2/+HDh9sJgl6YkDZw4EDf43r16hU9johtLEwiw0rhJqLlRLKqDi5fBjcjR45MtZ9Id7t27ay4+vDDD+02orlXXXWV3ebOGWtvcsKPqKgXZ1NxAj6nQvnpT7HeatoZK467a5QdfSyozbL7+8ekbeCOx9dff51qPwMBBmnM4XBPOk1P/xK5C1lThBAiDkS4+EHHosIqEfyYupUaiAhOnz7dPPjgg2br1q02Yo2A+fnnn62A51HibvUFhEFGQfi89tprVuicccYZ1hLRokULayN45ZVX7HkZPHhXegAGEIig+fPn2x98RKSbSMhqF/icETmU3ytechJZVQfEFccS5ezbt6/N65xzzrHXjQl/L7/8sr0TwqPIvdYC5gzccccdNhrLoKhNmzZ24h+RUPoIj23H93zppZemOB9WBeCcnIMVOlz0PKeBvx2rCaunYCdBTBOFZtDXuXNnu1JMdvSxoDbL7u8fNqOzzjrLRq+pO9eevw8M0j/55BNrRWLQjmUmo/1L5CLCXj9RCCFy+iPut2zZYp/aR3qevLd27dro0xUrVqzou/Z4pUqV7INCeOALn1lPOHYdY8oQBE8YJA3rLHvZtGmTfVR27Pl4mApPNqxTp06qdcRhzZo19smPQWulxz7wJZly8hjw2CdIeuHJheznyYIZXUc8vXVw61TTnkFs3rzZPoQlKF+euvjrr7+mOIaHzbgHxvi9eKLlhAkTUp2Ldce96Xi0e0bXEc/M6+PNk/W5/erWvXv3yPbt27Pt+gS1WRjfP/pKhw4dfM/JA5ReeeWVTOlfIvegiLgQIleCj5RI1jHHHJMwLcsCsqShi3SNHj3aRqNZjm3p0qX2dvy8efOsp5YJYkTJuP3OEmhbtmwx27ZtM//99180P5aTI1rIkm1BkAfHxq60gBeZ9YZZLm/ChAl2AhyT5ojSN2/e3Pzyyy92XfTYdaOJuBGV4xY5y+7hS2WCHRPbmITKWtOxJCont+DZH7RkHdF6Js/F2jPi4Ty1fnaD9NSB9qOMQcvUAdFe8mNy7vjx482SJUuslQGfMdehR48eqVa0IPI5YsQI60nmOnAMq4dw/YnUcgzXKpb77rvP5ktUFRtDMtFwIsLUgf6Undfn0UcftRHgt956y951qV69uq0X/cyPrLo+QW0WxvePvsJ3j+8gFpXly5fbvtCgQQMb8WZOSWb0L5F7yIMaD7sQQgghhAgfxC7WEoSxV7wKIbIGTdYUQgghhBAiBCTEhRBCCCGECAEJcSGEEEIIIUJAkzWFEEIIkfRERiFE5qHJmkIIIYQQQoSArClCCCGEEEKEgIS4EEIIIYQQISAhLoQQQgghRAhIiAshhBBCCBECEuJCCCGEEEKEgIS4EEIIIYQQISAhLoQQQgghRAhIiAshhBBCCBECEuJCCCGEEEKY7Of/AF0PRt6GXERrAAAAAElFTkSuQmCC", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "aa.plot_settings()\n", + "\n", + "importances = pipe.named_steps[\"clf\"].feature_importances_\n", + "order = np.argsort(importances)[-10:]\n", + "color = aa.plot_get_clist(n_colors=2)[0]\n", + "\n", + "fig, ax = plt.subplots(figsize=(7, 5))\n", + "ax.barh(np.arange(len(order)), importances[order], color=color)\n", + "ax.set_yticks(np.arange(len(order)))\n", + "ax.set_yticklabels([feature_names[i] for i in order], fontsize=8)\n", + "ax.set_xlabel(\"Random forest importance\")\n", + "ax.set_title(\"Top CPP features driving the scikit-learn model\")\n", + "plt.tight_layout()\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "c15-h5", + "metadata": {}, + "source": [ + "## 5. Scoring the next delivery from the same tool\n", + "\n", + "The fitted pipeline is now a predictor for anything that tool sends next. A new FASTA goes\n", + "through exactly the same two calls, and `transform` encodes it with the features chosen at\n", + "`fit` time, so the new matrix is column-compatible by construction." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "c16-batch", + "metadata": { + "execution": { + "iopub.execute_input": "2026-09-18T17:18:15.604469Z", + "iopub.status.busy": "2026-09-18T17:18:15.604405Z", + "iopub.status.idle": "2026-09-18T17:18:15.627065Z", + "shell.execute_reply": "2026-09-18T17:18:15.626784Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "feature matrix: (6, 25)\n", + "DataFrame shape: (6, 26)\n" + ] + }, + { + "data": { + "text/html": [ + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
 entryJMD_N_TMD_N-Pattern(C,4,8,12)-TANS770102TMD_C_JMD_C-Pattern(C,2,5,9,12)-OOBM850101JMD_N_TMD_N-Pattern(C,1,5,8)-RICJ880117JMD_N_TMD_N-Pattern(C,5,8)-FASG760105
1Q153030.9566700.5810000.4690000.221500
2P168820.5656700.6347500.3456700.491500
3P044390.8776700.5265000.2960000.229500
4P080690.5323300.6637500.6050000.664000
5P279300.4403300.5210000.2466700.442500
6Q9Y2190.7173300.6022500.3703300.369000
\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# A second, unlabeled delivery: six proteins the pipeline has never seen.\n", + "df_all = aa.load_dataset(name=\"DOM_GSEC\")\n", + "df_batch2 = df_all[~df_all[\"entry\"].isin(df_seq[\"entry\"])].head(6)\n", + "\n", + "file_batch2 = os.path.join(folder_upstream, \"upstream_batch2.fasta\")\n", + "aa.to_fasta(df_seq=df_batch2[[\"entry\", \"sequence\"]], file_path=file_batch2,\n", + " col_id=\"entry\", col_seq=\"sequence\", sep=\"|\", col_db=None, cols_info=None)\n", + "\n", + "df_new = aa.read_fasta(file_path=file_batch2, col_id=\"entry\", col_seq=\"sequence\",\n", + " sep=\"|\", col_db=None, cols_info=None)\n", + "\n", + "X_new = sft_fitted.transform(X=df_new)\n", + "df_X_new = pd.DataFrame(X_new, columns=feature_names)\n", + "df_X_new.insert(0, \"entry\", df_new[\"entry\"].to_numpy())\n", + "\n", + "print(\"feature matrix:\", X_new.shape)\n", + "aa.display_df(df=df_X_new, n_rows=10, n_cols=5, show_shape=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "c17-predict", + "metadata": { + "execution": { + "iopub.execute_input": "2026-09-18T17:18:15.628008Z", + "iopub.status.busy": "2026-09-18T17:18:15.627946Z", + "iopub.status.idle": "2026-09-18T17:18:15.665259Z", + "shell.execute_reply": "2026-09-18T17:18:15.665054Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "DataFrame shape: (6, 3)\n" + ] + }, + { + "data": { + "text/html": [ + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
 entrypredicted_labelp_substrate
1Q1530310.760000
2P1688210.690000
3P0443910.680000
4P0806900.480000
5P2793000.390000
6Q9Y21910.580000
\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "df_pred = pd.DataFrame({\"entry\": df_new[\"entry\"],\n", + " \"predicted_label\": pipe.predict(df_new),\n", + " \"p_substrate\": pipe.predict_proba(df_new)[:, 1].round(3)})\n", + "aa.display_df(df=df_pred, n_rows=10, show_shape=True)" + ] + }, + { + "cell_type": "markdown", + "id": "c18-recap", + "metadata": {}, + "source": [ + "## 6. Recap: the bridge in four lines\n", + "\n", + "Stripped of the narrative, the whole recipe is:\n", + "\n", + "```python\n", + "df_seq = aa.read_fasta(file_path=\"hits.fasta\", cols_info=[\"label\"]) # 1. read\n", + "pipe = Pipeline([(\"sft\", aa.SequenceFeatureTransformer(random_state=0)), # 2. bridge\n", + " (\"scaler\", StandardScaler()),\n", + " (\"clf\", RandomForestClassifier(random_state=0))])\n", + "pipe.fit(df_seq[[\"entry\", \"sequence\"]], df_seq[\"label\"].astype(int)) # 3. fit\n", + "pipe.predict(df_new) # 4. predict\n", + "```\n", + "\n", + "What to change for your own data:\n", + "\n", + "- **Header convention**: `sep`, `col_db` and `cols_info` in `aa.read_fasta` cover the usual\n", + " UniProt-style and tool-specific formats.\n", + "- **Domain boundaries**: if your upstream file has them, keep the `tmd_start` / `tmd_stop`\n", + " columns on the `df_seq` and `aa.SequenceFeature.get_df_parts` will slice real parts\n", + " instead of the sequence-level fallback, which is normally the stronger signal.\n", + "- **Selection budget**: `n_filter`, `max_cor` and `max_overlap` trade feature count against\n", + " redundancy; `split_kws` and `df_scales` set how wide CPP searches, and are the two levers\n", + " that dominate runtime.\n", + "\n", + "Where to go next: the :class:`~aaanalysis.CPP` tutorial for the feature engineering itself,\n", + "the *Embeddings & AlphaFold* tutorial for the embedding and structure bridges, and the\n", + "*P8: Prediction* protocol for the full prediction workflow this recipe feeds." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.13.11" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +}