{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Analyzing metabolic interactions\n", "\n", "Whereas the default results will show you which taxon consumes and produces which metabolite it is not immediately apparent which metabolic interactions that implies. Thus, we provide some helpers to quantify and summarize metabolic interactions between taxa.\n", "\n", "It should be noted that MICOM provides mechanistic interactions, thus they differ quite abit from correlations. First, they are calculated on a per sample basis and can thus differ between samples as well. They are also non-symmetric and directed and thus qualify as ecological interactions. The strategy used in `grow` workflow might also affect the predicted interactions. The most conservative (least interactions) will be predicted with parsimonious FBA because it will also minimize inter-taxon fluxes. The other strategies are somewhat more permissive for inter-taxon fluxes but may also include futile cycles (which will not appear in parsimonious FBA).\n", "\n", "Finally all-versus-all interactions can be somewhat slow for larger data sets due to the inherent combinatorial explosion. The complexity will scale with $n_{samples} \\cdot n^2_{taxa} \\cdot n_{metabolites}$.\n", "\n", "## Calculating focal interactions\n", "\n", "Interactions are obatined from a `GrowthResults` object as obtained by the `grow` workflow. By default they are based on a single taxon of interest (called a focal taxon) for which we will calculate all metabolic interactions with all other taxa in all samples. MICOM stratifies interactions into 3 ecological types shown below.\n", "\n", "![MICOM interaction types](_static/interactions.png)\n", "\n", "Let's see what that looks like by using a larger example result." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "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", "
metabolitefocalpartnerclassfluxsample_idnamemolecular_weightC_numberN_number...kegg.compoundlipidmapsmetanetx.chemicalpubchem.compoundreactomesboseed.compoundchebismilesreaction
2115ala_L[e]s__Akkermansia_muciniphilas__Bacteroides_fragilisprovided11.238551S_SRR5935812L-alanine89.0931831...C00041NaNMNXM11057325950.0NaNSBO:0000247cpd00035CHEBI:16977NaNEX_ala_L(e)
2141lac_D[e]s__Akkermansia_muciniphilas__Bacteroides_fragilisprovided11.141526S_SRR5935812D-lactate89.0700030...C00256NaNMNXM73183561503.0NaNSBO:0000247cpd00221CHEBI:42111NaNEX_lac_D(e)
1080acald[e]s__Akkermansia_muciniphilas__Escherichia_colireceived9.277781S_SRR5935769Acetaldehyde44.0525620...C00084NaNMNXM75177.0NaNSBO:0000247cpd00071CHEBI:15343NaNEX_acald(e)
1120pro_L[e]s__Akkermansia_muciniphilas__Escherichia_colireceived9.208372S_SRR5935769L-proline115.1304651...C00148;C000763NaNMNXM114145742.0NaNSBO:0000247cpd00129CHEBI:17203NaNEX_pro_L(e)
1094etoh[e]s__Akkermansia_muciniphilas__Escherichia_colireceived8.980545S_SRR5935769Ethanol46.0684420...C00469NaNMNXM734299702.0NaNSBO:0000247cpd00363CHEBI:16236NaNEX_etoh(e)
\n", "

5 rows × 24 columns

\n", "
" ], "text/plain": [ " metabolite focal partner \\\n", "2115 ala_L[e] s__Akkermansia_muciniphila s__Bacteroides_fragilis \n", "2141 lac_D[e] s__Akkermansia_muciniphila s__Bacteroides_fragilis \n", "1080 acald[e] s__Akkermansia_muciniphila s__Escherichia_coli \n", "1120 pro_L[e] s__Akkermansia_muciniphila s__Escherichia_coli \n", "1094 etoh[e] s__Akkermansia_muciniphila s__Escherichia_coli \n", "\n", " class flux sample_id name molecular_weight \\\n", "2115 provided 11.238551 S_SRR5935812 L-alanine 89.09318 \n", "2141 provided 11.141526 S_SRR5935812 D-lactate 89.07000 \n", "1080 received 9.277781 S_SRR5935769 Acetaldehyde 44.05256 \n", "1120 received 9.208372 S_SRR5935769 L-proline 115.13046 \n", "1094 received 8.980545 S_SRR5935769 Ethanol 46.06844 \n", "\n", " C_number N_number ... kegg.compound lipidmaps metanetx.chemical \\\n", "2115 3 1 ... C00041 NaN MNXM1105732 \n", "2141 3 0 ... C00256 NaN MNXM731835 \n", "1080 2 0 ... C00084 NaN MNXM75 \n", "1120 5 1 ... C00148;C000763 NaN MNXM114 \n", "1094 2 0 ... C00469 NaN MNXM734299 \n", "\n", " pubchem.compound reactome sbo seed.compound chebi \\\n", "2115 5950.0 NaN SBO:0000247 cpd00035 CHEBI:16977 \n", "2141 61503.0 NaN SBO:0000247 cpd00221 CHEBI:42111 \n", "1080 177.0 NaN SBO:0000247 cpd00071 CHEBI:15343 \n", "1120 145742.0 NaN SBO:0000247 cpd00129 CHEBI:17203 \n", "1094 702.0 NaN SBO:0000247 cpd00363 CHEBI:16236 \n", "\n", " smiles reaction \n", "2115 NaN EX_ala_L(e) \n", "2141 NaN EX_lac_D(e) \n", "1080 NaN EX_acald(e) \n", "1120 NaN EX_pro_L(e) \n", "1094 NaN EX_etoh(e) \n", "\n", "[5 rows x 24 columns]" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from micom.data import test_results\n", "from micom.interaction import interactions\n", "\n", "results = test_results()\n", "ints = interactions(results, taxa=\"s__Akkermansia_muciniphila\")\n", "ints.sort_values(by=\"flux\", ascending=False).head()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "So you see the individual metabolite flux between the pair of taxa and the interaction class in each single sample. This is quite detailed and can tell you a lot, but we can also summarize it to the overall fluxes between two taxa in a sample." ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "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", "
sample_idfocalpartnerclassfluxmass_fluxC_fluxN_fluxn_ints
0S_SRR5935769s__Akkermansia_muciniphilas__Alistipes_finegoldiico-consumed7.3492600.53565916.3892352.6996648
1S_SRR5935769s__Akkermansia_muciniphilas__Alistipes_finegoldiiprovided3.1807560.34265313.2097272.5601376
2S_SRR5935769s__Akkermansia_muciniphilas__Alistipes_finegoldiireceived1.5136320.32105213.0306122.9671286
3S_SRR5935769s__Akkermansia_muciniphilas__Alistipes_onderdonkiico-consumed2.3294650.2595268.7345201.7381148
4S_SRR5935769s__Akkermansia_muciniphilas__Alistipes_onderdonkiiprovided0.9061430.1127545.4901180.7647954
\n", "
" ], "text/plain": [ " sample_id focal partner \\\n", "0 S_SRR5935769 s__Akkermansia_muciniphila s__Alistipes_finegoldii \n", "1 S_SRR5935769 s__Akkermansia_muciniphila s__Alistipes_finegoldii \n", "2 S_SRR5935769 s__Akkermansia_muciniphila s__Alistipes_finegoldii \n", "3 S_SRR5935769 s__Akkermansia_muciniphila s__Alistipes_onderdonkii \n", "4 S_SRR5935769 s__Akkermansia_muciniphila s__Alistipes_onderdonkii \n", "\n", " class flux mass_flux C_flux N_flux n_ints \n", "0 co-consumed 7.349260 0.535659 16.389235 2.699664 8 \n", "1 provided 3.180756 0.342653 13.209727 2.560137 6 \n", "2 received 1.513632 0.321052 13.030612 2.967128 6 \n", "3 co-consumed 2.329465 0.259526 8.734520 1.738114 8 \n", "4 provided 0.906143 0.112754 5.490118 0.764795 4 " ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from micom.interaction import summarize_interactions\n", "\n", "summary = summarize_interactions(ints)\n", "summary.head()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This calculates the overall flux in each class for the pair of taxa. It also provides some more meaningful eestimates of flux such as the exchanged mass, carbon or nitrogen. So in this example you see that Akkermansia competes for most of the mass with Alistipes but actually receives more nitrogen from Alistipes than it competes for in that sample." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Calculating all interactions\n", "\n", "It's also possible to calculate all interactions, just be aware that this (1) generates a lot of data and (2) will take a while for larger data sets. You can parallelize the analysis over each taxon by providing the the `threads` argument. Simply provide `None` for the taxa to obtain all interactions." ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "350423eff34b4836a8570d1365f2fd9b", "version_major": 2, "version_minor": 0 }, "text/plain": [ "Output()" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n"
      ],
      "text/plain": []
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "
\n",
       "
\n" ], "text/plain": [ "\n" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "(1115688, 24)" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "full = interactions(results, taxa=None, threads=8)\n", "full.shape" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This generates quite a lot of results, but we can again use a summary." ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(117108, 9)" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "full_summary = summarize_interactions(full)\n", "full_summary.shape" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Metabolic Exchange Score\n", "\n", "For a slightly more global view on exchanges we also provide calculation of the Metabolic Exchange Score (MES) by Marcelino et al., which is decribed [in detail here](https://doi.org/10.1038/s41467-023-42112-w). The MES is the geometric mean of the number of producers P and consumers C of a metabolite m in a single sample i, given by:\n", "\n", "$$\n", "MES^i_m = 2\\cdot\\frac{P^i_m\\cdot C^i_m}{P^i_m + C^i_m}\n", "$$\n", "\n", "This can be interpreted as a normalized number of all observed metabolic interactions (becuse $P\\cdot C$ is the number of all possible directed combinations of producers and consumers). So it is a measure of cross-feeding. \n", "\n", "It can also be calculated very fast for large data sets, so let's go." ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "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", "
metabolitesample_idMESnamemolecular_weightC_numberN_numberbigg.metabolitebiocychmdb...kegg.compoundlipidmapsmetanetx.chemicalpubchem.compoundreactomesboseed.compoundchebismilesreaction
012dhchol[e]S_SRR59357694.80000012-Dehydrocholate405.5475824012dhcholNaNNaN...NaNNaNNaNNaNNaNSBO:0000247NaNNaNNaNEX_12dhchol(e)
112dhchol[e]S_SRR59358124.80000012-Dehydrocholate405.5475824012dhcholNaNNaN...NaNNaNNaNNaNNaNSBO:0000247NaNNaNNaNEX_12dhchol(e)
212dhchol[e]S_SRR59358163.42857112-Dehydrocholate405.5475824012dhcholNaNNaN...NaNNaNNaNNaNNaNSBO:0000247NaNNaNNaNEX_12dhchol(e)
312dhchol[e]S_SRR59358434.44444412-Dehydrocholate405.5475824012dhcholNaNNaN...NaNNaNNaNNaNNaNSBO:0000247NaNNaNNaNEX_12dhchol(e)
412dhchol[e]S_SRR59359244.44444412-Dehydrocholate405.5475824012dhcholNaNNaN...NaNNaNNaNNaNNaNSBO:0000247NaNNaNNaNEX_12dhchol(e)
\n", "

5 rows × 21 columns

\n", "
" ], "text/plain": [ " metabolite sample_id MES name molecular_weight \\\n", "0 12dhchol[e] S_SRR5935769 4.800000 12-Dehydrocholate 405.54758 \n", "1 12dhchol[e] S_SRR5935812 4.800000 12-Dehydrocholate 405.54758 \n", "2 12dhchol[e] S_SRR5935816 3.428571 12-Dehydrocholate 405.54758 \n", "3 12dhchol[e] S_SRR5935843 4.444444 12-Dehydrocholate 405.54758 \n", "4 12dhchol[e] S_SRR5935924 4.444444 12-Dehydrocholate 405.54758 \n", "\n", " C_number N_number bigg.metabolite biocyc hmdb ... kegg.compound \\\n", "0 24 0 12dhchol NaN NaN ... NaN \n", "1 24 0 12dhchol NaN NaN ... NaN \n", "2 24 0 12dhchol NaN NaN ... NaN \n", "3 24 0 12dhchol NaN NaN ... NaN \n", "4 24 0 12dhchol NaN NaN ... NaN \n", "\n", " lipidmaps metanetx.chemical pubchem.compound reactome sbo \\\n", "0 NaN NaN NaN NaN SBO:0000247 \n", "1 NaN NaN NaN NaN SBO:0000247 \n", "2 NaN NaN NaN NaN SBO:0000247 \n", "3 NaN NaN NaN NaN SBO:0000247 \n", "4 NaN NaN NaN NaN SBO:0000247 \n", "\n", " seed.compound chebi smiles reaction \n", "0 NaN NaN NaN EX_12dhchol(e) \n", "1 NaN NaN NaN EX_12dhchol(e) \n", "2 NaN NaN NaN EX_12dhchol(e) \n", "3 NaN NaN NaN EX_12dhchol(e) \n", "4 NaN NaN NaN EX_12dhchol(e) \n", "\n", "[5 rows x 21 columns]" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from micom.interaction import MES\n", "\n", "scores = MES(results)\n", "scores.head()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "All of the computed interaction measures also have [matching visualizations](viz.html)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [] } ], "metadata": { "kernelspec": { "display_name": "micom", "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.11.8" } }, "nbformat": 4, "nbformat_minor": 2 }