{ "cells": [ { "cell_type": "code", "execution_count": 19, "id": "1b255660-052d-4d02-8422-f296061d5bf1", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Python: /opt/conda/envs/meenv/bin/python3.10\n", "COBRApy: 0.24.0\n", "solver: glpk_exact, status: optimal, growth: 10.0\n", "fluxes:\n", " EX_a_c -10.0\n", "R 10.0\n", "BIOM 10.0\n", "Name: fluxes, dtype: float64\n" ] } ], "source": [ "# Corrected GLPK sanity: add an uptake source for a_c so biomass can grow\n", "import cobra, sys\n", "from cobra import Model, Reaction, Metabolite\n", "\n", "print(\"Python:\", sys.executable)\n", "print(\"COBRApy:\", cobra.__version__)\n", "\n", "m = Model(\"smoke_ok\")\n", "\n", "# metabolites\n", "a = Metabolite(\"a_c\", name=\"a\")\n", "b = Metabolite(\"b_c\", name=\"b\")\n", "\n", "# uptake of a from environment (EX_a: a_c <-> ; lb < 0 allows import)\n", "EX_a = Reaction(\"EX_a_c\")\n", "EX_a.lower_bound = -10.0 # allow uptake of 10 units\n", "EX_a.upper_bound = 1000.0\n", "EX_a.add_metabolites({a: -1.0})\n", "\n", "# conversion a -> b\n", "R = Reaction(\"R\")\n", "R.lower_bound = 0.0\n", "R.upper_bound = 1000.0\n", "R.add_metabolites({a: -1.0, b: +1.0})\n", "\n", "# biomass consumes b\n", "BIOM = Reaction(\"BIOM\")\n", "BIOM.lower_bound = 0.0\n", "BIOM.upper_bound = 1000.0\n", "BIOM.add_metabolites({b: -1.0})\n", "\n", "m.add_reactions([EX_a, R, BIOM])\n", "m.objective = \"BIOM\"\n", "\n", "# choose solver (GLPK exact if available)\n", "try:\n", " m.solver = \"glpk_exact\"\n", " solver_used = \"glpk_exact\"\n", "except Exception:\n", " m.solver = \"glpk\"\n", " solver_used = \"glpk\"\n", "\n", "sol = m.optimize()\n", "print(f\"solver: {solver_used}, status: {sol.status}, growth: {sol.objective_value}\")\n", "print(\"fluxes:\\n\", sol.fluxes[[\"EX_a_c\",\"R\",\"BIOM\"]])\n", "\n" ] }, { "cell_type": "code", "execution_count": 2, "id": "b19b9f06-0527-468f-b7aa-d95d1e8081d9", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "COBRApy: 0.24.0\n", "Optlang : 1.8.0\n", "Solvers : {'cplex': , 'glpk_exact': , 'glpk': , 'scipy': }\n", "CPLEX : 22.1.2.0\n", "ETFL import OK\n" ] } ], "source": [ "import cobra, optlang\n", "from cobra.util import solver\n", "import cplex, etfl\n", "print(\"COBRApy:\", cobra.__version__)\n", "print(\"Optlang :\", optlang.__version__)\n", "print(\"Solvers :\", solver.solvers)\n", "print(\"CPLEX :\", cplex.Cplex().get_version())\n", "print(\"ETFL import OK\")\n", "\n", "\n" ] }, { "cell_type": "code", "execution_count": 3, "id": "a9e36d41-3e64-4365-8a45-b531d716a66c", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Interpreter: /opt/conda/envs/meenv/bin/python3.10\n", "If you just installed ETFL, a Kernel ▶ Restart is recommended.\n" ] } ], "source": [ "# If imports still reflect old versions, restart the kernel from the UI after this cell.\n", "import sys\n", "print(\"Interpreter:\", sys.executable)\n", "print(\"If you just installed ETFL, a Kernel ▶ Restart is recommended.\")\n" ] }, { "cell_type": "code", "execution_count": 4, "id": "35691cf6-70c5-4959-8648-15a78ea22cbd", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Genome GBFF files found: ['/workspace/data/genome/genomic.gbff']\n", "Protein FAA files found: ['/workspace/data/genome/pputida_KT2440.faa', '/workspace/data/genome/pputida_KT2440_full.faa', '/workspace/data/genome/protein.faa']\n", "COBRA default solver set to: \n", "\n", "Interpreter: /opt/conda/envs/meenv/bin/python3.10\n", "NumPy : 1.23.5\n", "pandas: 1.5.3\n", "COBRA : 0.24.0\n", "ETFL : OK\n" ] } ], "source": [ "# === Cell 1: Imports & config (agnostic to ETFL layout) ===\n", "import os, sys, json, math, random, gzip, shutil, textwrap, re\n", "from pathlib import Path\n", "from collections import defaultdict, Counter\n", "\n", "import numpy as np\n", "import pandas as pd\n", "\n", "# Core COBRA/solver\n", "import cobra\n", "from cobra.io import read_sbml_model\n", "from cobra import Model, Reaction, Metabolite\n", "from optlang.symbolics import Zero\n", "\n", "# Just import top-level ETFL to confirm install; we'll import classes in Cell 2\n", "import etfl\n", "\n", "# IO / plotting\n", "import matplotlib.pyplot as plt\n", "import seaborn as sns\n", "\n", "# BLAST and sequence handling\n", "from Bio import SeqIO\n", "\n", "# Reproducibility\n", "random.seed(42)\n", "np.random.seed(42)\n", "\n", "# ---- Paths inside the Docker container ----\n", "BASE = Path(\"/workspace\")\n", "DATA = BASE / \"data\"\n", "GENOME_DIR = DATA / \"genome\"\n", "GEM_DIR = DATA / \"gem\"\n", "RES = BASE / \"results\"\n", "RES.mkdir(exist_ok=True, parents=True)\n", "\n", "# SBML model location\n", "IJN1463_URL = \"https://bigg.ucsd.edu/static/models/iJN1463.xml\"\n", "IJN1463_FILE = GEM_DIR / \"iJN1463.xml\"\n", "\n", "# List available genome/model files\n", "gbff_files = list(GENOME_DIR.rglob(\"*.gbff\")) + list(GENOME_DIR.rglob(\"*.gbk\")) + list(GENOME_DIR.rglob(\"*.genbank\"))\n", "faa_files = list(GENOME_DIR.rglob(\"*.faa\"))\n", "gff_files = list(GENOME_DIR.rglob(\"*.gff\")) + list(GENOME_DIR.rglob(\"*.gff3\"))\n", "\n", "print(\"Genome GBFF files found:\", [str(p) for p in gbff_files])\n", "print(\"Protein FAA files found:\", [str(p) for p in faa_files])\n", "\n", "# Ensure the GEM is present (download if missing)\n", "import urllib.request\n", "if not IJN1463_FILE.exists():\n", " GEM_DIR.mkdir(exist_ok=True, parents=True)\n", " print(\"Downloading iJN1463 SBML model from BiGG ...\")\n", " urllib.request.urlretrieve(IJN1463_URL, IJN1463_FILE)\n", "\n", "assert IJN1463_FILE.exists(), \"iJN1463 SBML model could not be found or downloaded.\"\n", "\n", "# ---- Force CPLEX as default solver ----\n", "try:\n", " cobra.Configuration().solver = \"cplex\"\n", " print(\"COBRA default solver set to:\", cobra.Configuration().solver)\n", "except Exception as e:\n", " print(\"Warning: could not set COBRA default solver to CPLEX:\", e)\n", "\n", "# ---- Sanity: show interpreter and versions ----\n", "print(\"\\nInterpreter:\", sys.executable)\n", "print(\"NumPy :\", np.__version__)\n", "print(\"pandas:\", pd.__version__)\n", "print(\"COBRA :\", cobra.__version__)\n", "print(\"ETFL :\", getattr(etfl, '__version__', 'OK'))\n" ] }, { "cell_type": "code", "execution_count": 5, "id": "90f26d88-585c-4f43-b91e-9f68cd8f1d69", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Using genome file: /workspace/data/genome/genomic.gbff\n", "Using protein FASTA: /workspace/data/genome/pputida_KT2440_full.faa\n", "Total CDS parsed: 4102 | unique gene IDs: 4063\n", "Example gene entry: [('A0T30_RS00005', {'locus': 'A0T30_RS00005', 'product': 'gspe/pule family protein', 'nt_len': 1740, 'protein_id': 'WP_021699927.1', 'aa_len': 579, 'aa_counts': {'A': 59, 'C': 6, 'D': 33, 'E': 44, 'F': 15, 'G': 39, 'H': 10, 'I': 25, 'K': 21, 'L': 78, 'M': 19, 'N': 14, 'P': 21, 'Q': 31, 'R': 45, 'S': 32, 'T': 28, 'V': 49, 'W': 1, 'Y': 9}})]\n", "Identified 59 ribosomal protein genes, 19 RNAP subunit genes.\n", "Identified 95 tRNA entries, 24 chaperones, 33 proteases.\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "/opt/conda/envs/meenv/lib/python3.10/site-packages/Bio/Seq.py:2879: BiopythonWarning: Partial codon, len(sequence) not a multiple of three. Explicitly trim the sequence or add trailing N before translation. This may become an error in future.\n", " warnings.warn(\n" ] } ], "source": [ "# === Cell 2: Parse genome annotation ===\n", "assert gbff_files, \"No GenBank genome file (.gbff/.gbk) found for P. alcaligenes. Put one in data/genome.\"\n", "\n", "# pick the largest GenBank file (if multiple assemblies/contigs exist)\n", "gbff_path = max(gbff_files, key=lambda p: p.stat().st_size)\n", "print(\"Using genome file:\", gbff_path)\n", "\n", "# ---------- containers ----------\n", "gene_info = {} # gid -> dict(locus, product, nt_len, aa_len, aa_counts, protein_id)\n", "gene_to_protein_id = {} # gid -> RefSeq protein accession (if any)\n", "ribosomal_genes = set()\n", "rnap_genes = set()\n", "trna_genes = []\n", "protease_genes = set()\n", "chaperone_genes = set()\n", "\n", "# ---------- load FAA (protein FASTA) if present ----------\n", "prot_seqs = {} # protein_id -> protein sequence\n", "prot_by_locus = {} # locus_tag -> protein sequence (when headers contain locus)\n", "if faa_files:\n", " faa_path = max(faa_files, key=lambda p: p.stat().st_size)\n", " print(\"Using protein FASTA:\", faa_path)\n", " for rec in SeqIO.parse(str(faa_path), \"fasta\"):\n", " pid = rec.id.split()[0]\n", " prot_seqs[pid] = str(rec.seq)\n", " # a fair number of NCBI protein FASTAs include locus in the description → try to catch it\n", " desc = rec.description\n", " # crude scan for locus_tag like 'locus_tag=PA1234' or ' [locus_tag=...]'\n", " m = re.search(r\"locus_tag=([\\w\\-\\.:]+)\", desc)\n", " if m:\n", " prot_by_locus[m.group(1)] = str(rec.seq)\n", "\n", "# ---------- helpers ----------\n", "AA20 = \"ACDEFGHIKLMNPQRSTVWY\"\n", "\n", "def aa_count_dict(seq: str):\n", " c = Counter(seq)\n", " return {aa: int(c.get(aa, 0)) for aa in AA20}\n", "\n", "def _safe_lower(s):\n", " try: return s.lower()\n", " except: return str(s).lower()\n", "\n", "def translate_cds_feature(record, feat, table=11):\n", " \"\"\"\n", " Fallback: translate CDS from genomic DNA when FAA/translation qualifiers are missing.\n", " Uses bacterial/archaeal/plastid code (11) by default.\n", " \"\"\"\n", " try:\n", " seq = feat.extract(record.seq) # handles strand/orientation\n", " prot = str(seq.translate(table=table, to_stop=True))\n", " # quick sanity: length multiple of 1, no internal stop except last\n", " return prot\n", " except Exception:\n", " return \"\"\n", "\n", "# ---------- parse GenBank ----------\n", "n_cds = 0\n", "for record in SeqIO.parse(str(gbff_path), \"genbank\"):\n", " for feat in getattr(record, \"features\", []):\n", " if feat.type != \"CDS\":\n", " # pick up tRNA quickly for counting downstream\n", " if feat.type.lower() == \"trna\":\n", " # try to name like \"tRNA-xxx\"\n", " name = None\n", " if \"gene\" in feat.qualifiers:\n", " name = feat.qualifiers[\"gene\"][0]\n", " elif \"product\" in feat.qualifiers:\n", " name = feat.qualifiers[\"product\"][0]\n", " trna_genes.append((name or \"tRNA\",))\n", " continue\n", "\n", " n_cds += 1\n", " quals = feat.qualifiers\n", " locus = quals.get(\"locus_tag\", [\"\"])[0]\n", " gene_name = quals.get(\"gene\", [locus])[0] or locus\n", " product = _safe_lower(quals.get(\"product\", [\"\"])[0])\n", "\n", " # CDS length in nucleotides\n", " try:\n", " nt_len = int(len(feat.location))\n", " except Exception:\n", " # fallback: end-start\n", " nt_len = int(feat.location.end) - int(feat.location.start)\n", "\n", " # protein accession (if present)\n", " protein_id = quals.get(\"protein_id\", [\"\"])[0]\n", "\n", " # protein sequence preference: FAA → /translation → computed translation → (unknown)\n", " prot_seq = \"\"\n", " if protein_id and protein_id in prot_seqs:\n", " prot_seq = prot_seqs[protein_id]\n", " elif locus and locus in prot_by_locus:\n", " prot_seq = prot_by_locus[locus]\n", " elif \"translation\" in quals:\n", " prot_seq = str(quals[\"translation\"][0]).replace(\" \", \"\").replace(\"\\n\", \"\")\n", " else:\n", " prot_seq = translate_cds_feature(record, feat, table=11) # bacterial code\n", "\n", " aa_len = len(prot_seq) if prot_seq else 0\n", " aa_counts = aa_count_dict(prot_seq) if prot_seq else {}\n", "\n", " # gene id to use downstream = prefer gene symbol, else locus\n", " gid = (gene_name or locus).replace(\" \", \"_\")\n", "\n", " gene_info[gid] = {\n", " \"locus\": locus,\n", " \"product\": product,\n", " \"nt_len\": nt_len,\n", " \"protein_id\": protein_id,\n", " \"aa_len\": aa_len,\n", " \"aa_counts\": aa_counts\n", " }\n", " gene_to_protein_id[gid] = protein_id\n", "\n", " # ---------- categorisation ----------\n", " # ribosomal proteins\n", " if (\"ribosomal protein\" in product) or product.startswith(\"30s ribosomal\") or product.startswith(\"50s ribosomal\"):\n", " ribosomal_genes.add(gid)\n", "\n", " # RNA polymerase subunits\n", " if (\"rna polymerase\" in product) or product.startswith(\"dna-directed rna polymerase\"):\n", " rnap_genes.add(gid)\n", "\n", " # tRNA (CDS-encoded tRNA is rare, but catch any)\n", " if product.startswith(\"trna-\") or product.startswith(\"trna \"):\n", " trna_genes.append(gid)\n", "\n", " # proteases (ATP-dependent + common names)\n", " if any(k in product for k in [\"lon protease\", \"clpx\", \"clpp\", \"hsluv\", \"ftsh\", \"protease\"]):\n", " protease_genes.add(gid)\n", "\n", " # chaperones\n", " if any(k in product for k in [\"dnak\", \"dnaj\", \"groel\", \"groes\", \"chaperone\", \"heat shock protein\"]):\n", " chaperone_genes.add(gid)\n", "\n", "print(f\"Total CDS parsed: {n_cds} | unique gene IDs: {len(gene_info)}\")\n", "# show one example entry with non-empty AA length if possible\n", "example_items = [kv for kv in gene_info.items() if kv[1].get(\"aa_len\", 0) > 0] or list(gene_info.items())\n", "print(\"Example gene entry:\", example_items[:1])\n", "print(f\"Identified {len(ribosomal_genes)} ribosomal protein genes, {len(rnap_genes)} RNAP subunit genes.\")\n", "print(f\"Identified {len(trna_genes)} tRNA entries, {len(chaperone_genes)} chaperones, {len(protease_genes)} proteases.\")\n" ] }, { "cell_type": "code", "execution_count": 6, "id": "947bd07b-999e-49de-a64a-14644bd8e906", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Protein source counts: Counter({'faa': 4047, 'gbk-translation': 16})\n" ] } ], "source": [ "from collections import Counter\n", "src = Counter(\n", " \"faa\" if info[\"protein_id\"] and info[\"aa_len\"]>0 else\n", " \"gbk-translation\" if info[\"aa_len\"]>0 and info[\"protein_id\"]==\"\" else\n", " \"fallback\" if info[\"aa_len\"]>0 else \"no-protein\"\n", " for info in gene_info.values()\n", ")\n", "print(\"Protein source counts:\", src)\n" ] }, { "cell_type": "code", "execution_count": 64, "id": "71608933-81a6-497d-bfea-782b759fcab5", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "\n", "Building a new DB, current time: 10/08/2025 10:41:14\n", "New DB name: /workspace/palc_db\n", "New DB title: /workspace/data/genome/protein.faa\n", "Sequence type: Protein\n", "Keep MBits: T\n", "Maximum file size: 1000000000B\n", "Adding sequences from FASTA; added 4081 sequences in 0.097878 seconds.\n", "\n", "\n", "Building a new DB, current time: 10/08/2025 10:41:14\n", "New DB name: /workspace/putida_db\n", "New DB title: /workspace/data/genome/pputida_KT2440_full.faa\n", "Sequence type: Protein\n", "Keep MBits: T\n", "Maximum file size: 1000000000B\n", "Adding sequences from FASTA; added 5527 sequences in 0.140005 seconds.\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "Warning: [blastp] Examining 5 or more matches is recommended\n", "Warning: [blastp] Examining 5 or more matches is recommended\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Total PP_#### mapped to P. alcaligenes: 2594\n", "sp|Q88FF8|CHRR_PSEPK → A0T30_RS20215\n", "sp|Q88L02|FADB_PSEPK → A0T30_RS14515\n", "sp|Q88LS1|EARP_PSEPK → A0T30_RS14025\n", "sp|Q88M11|MUPP_PSEPK → A0T30_RS15235\n", "sp|Q88Q83|GLYOX_PSEPK → A0T30_RS18795\n", "sp|Q88QT2|MURU_PSEPK → A0T30_RS20070\n", "sp|P0A171|RP54_PSEPK → A0T30_RS05620\n", "sp|Q88BX6|GLMU_PSEPK → A0T30_RS01915\n", "tr|Q88C96|Q88C96_PSEPK → A0T30_RS01005\n", "sp|Q88CT0|IXTPA_PSEPK → A0T30_RS03445\n" ] } ], "source": [ "# === Cell 3: Load scaffold GEM and prepare ortholog mapping + BLASTP refinement ===\n", "from cobra.io import read_sbml_model, load_json_model\n", "import subprocess, shlex, tempfile\n", "\n", "# ---- 0) robust loader for iJN1463 ----\n", "def _looks_like_sbml(path: Path) -> bool:\n", " try:\n", " with open(path, \"rb\") as fh:\n", " head = fh.read(1024).lower()\n", " return b\"= 30 and pid2 >= 30 and aln1 >= 70 and aln2 >= 70:\n", " mapped = palc_protein_to_gene.get(palc_prot, palc_prot)\n", " name_map[pp_id] = mapped\n", "\n", "# --- 6. Show results ---\n", "print(f\"Total PP_#### mapped to P. alcaligenes: {len(name_map)}\")\n", "for i, (pp, gid) in enumerate(name_map.items()):\n", " if i >= 10: break\n", " print(f\"{pp} → {gid}\")\n", "\n", "\n", "\n" ] }, { "cell_type": "code", "execution_count": 46, "id": "ac309b16-9da8-4106-8f24-23aa658330e6", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Copying COBRA scaffold…\n", "ETFL model ready: 2927 rxns, 2143 mets\n", "Registered ribosome & RNAP placeholders (composition will be defined later).\n", "ATPM adjusted: LB=8.39, UB=1000\n", "Global parameters & maintenance set; CPLEX active.\n" ] } ], "source": [ "# === Cell 4: Initialize ETFL model and global parameters (literature-anchored) ===\n", "import importlib, pkgutil, inspect, math\n", "from copy import deepcopy\n", "import etfl\n", "from cobra import Metabolite\n", "\n", "# discover model class\n", "def discover_model_class():\n", " visited, q = set(), [(\"etfl\", etfl)]\n", " while q:\n", " mname, mod = q.pop(0)\n", " if mname in visited: continue\n", " visited.add(mname)\n", " for n in dir(mod):\n", " obj = getattr(mod, n)\n", " if isinstance(obj, type):\n", " if n in (\"ExpressionModel\",\"MEModel\",\"ETFLModel\"): return obj,mname\n", " try:\n", " sig = inspect.signature(obj.__init__)\n", " if any(p.name==\"cobra_model\" for p in sig.parameters.values()):\n", " return obj,mname\n", " except Exception: pass\n", " if hasattr(mod,\"__path__\"):\n", " for _,sub,_ in pkgutil.iter_modules(mod.__path__):\n", " try:q.append((f\"{mname}.{sub}\",importlib.import_module(f\"{mname}.{sub}\")))\n", " except:pass\n", " return None,None\n", "\n", "ModelClass,_ = discover_model_class()\n", "assert ModelClass,\"ETFL model class not found.\"\n", "from etfl.core.enzyme import Enzyme,Ribosome,RNAPolymerase\n", "\n", "# build model\n", "try: etfl_model = ModelClass(name=\"P_alcaligenes_ETFL\",cobra_model=model)\n", "except TypeError: etfl_model = ModelClass(name=\"P_alcaligenes_ETFL\")\n", "\n", "# force CPLEX\n", "etfl_model.solver=\"cplex\"\n", "if len(etfl_model.reactions)==0:\n", " print(\"Copying COBRA scaffold…\")\n", " etfl_model.add_reactions([rxn.copy() for rxn in model.reactions])\n", "print(f\"ETFL model ready: {len(etfl_model.reactions)} rxns, {len(etfl_model.metabolites)} mets\")\n", "\n", "# literature-anchored parameters\n", "translation_elongation_rate=18.0 # aa s⁻¹ (E. coli / Pseudomonas)\n", "transcription_elongation_rate=60.0 # nt s⁻¹\n", "kdeg_mRNA_s=math.log(2)/120 # 2 min half-life\n", "kdeg_prot_s=math.log(2)/(20*3600) # 20 h half-life\n", "NGAM_ATP=8.39 # mmol ATP gDW⁻¹ h⁻¹\n", "\n", "etfl_model._expr_params=dict(\n", " translation_elongation_rate=translation_elongation_rate,\n", " transcription_elongation_rate=transcription_elongation_rate,\n", " kdeg_mRNA_s=kdeg_mRNA_s,\n", " kdeg_prot_s=kdeg_prot_s,\n", " NGAM_ATP=NGAM_ATP\n", ")\n", "\n", "# machinery placeholders (composition filled later)\n", "rib = Ribosome(id=\"ribosome\", kribo=translation_elongation_rate, composition={}, rrna=[])\n", "rnp = RNAPolymerase(id=\"RNA_polymerase\", ktrans=transcription_elongation_rate, composition={})\n", "etfl_model.ribosomes = getattr(etfl_model,\"ribosomes\",[])+[rib]\n", "etfl_model.rna_polymerases = getattr(etfl_model,\"rna_polymerases\",[])+[rnp]\n", "print(\"Registered ribosome & RNAP placeholders (composition will be defined later).\")\n", "\n", "# ensure currency metabolites\n", "def get_or_add(mid,name,c=\"c\"):\n", " try:return etfl_model.metabolites.get_by_id(mid)\n", " except KeyError:\n", " m=Metabolite(mid,name=name,compartment=c);etfl_model.add_metabolites([m]);return m\n", "ATP=get_or_add(\"atp_c\",\"ATP\");ADP=get_or_add(\"adp_c\",\"ADP\");PI=get_or_add(\"pi_c\",\"Phosphate\")\n", "H2O=get_or_add(\"h2o_c\",\"H2O\");H=get_or_add(\"h_c\",\"H+\");AA=get_or_add(\"aa_c\",\"Generic amino acids\")\n", "\n", "# fix ATPM bounds safely\n", "for rid in (\"ATPM\",\"ATPM_c\",\"DM_atp_c_\"):\n", " if rid in etfl_model.reactions:\n", " r=etfl_model.reactions.get_by_id(rid)\n", " r.upper_bound=max(r.upper_bound,1000);r.lower_bound=min(r.upper_bound,NGAM_ATP)\n", " print(f\"ATPM adjusted: LB={r.lower_bound}, UB={r.upper_bound}\")\n", " break\n", "\n", "print(\"Global parameters & maintenance set; CPLEX active.\")\n" ] }, { "cell_type": "code", "execution_count": 78, "id": "a2e287f4-c452-47b2-b80c-2fd76b76e4a2", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "✅ ETFL synthetic module ready.\n", "Added: ['TX_tpl', 'TL_tpl', 'TPL', 'MAZF_cleavage']\n" ] } ], "source": [ "from cobra import Metabolite, Reaction\n", "from etfl.core.genes import Gene\n", "import math\n", "\n", "# === 0. Utility ===\n", "def get_or_add(mid, name=None, c=\"c\"):\n", " try:\n", " return etfl_model.metabolites.get_by_id(mid)\n", " except KeyError:\n", " m = Metabolite(mid, name=name or mid, compartment=c)\n", " etfl_model.add_metabolites([m])\n", " return m\n", "\n", "def safe_add_gene(gene):\n", " if gene.id not in [g.id for g in etfl_model.genes]:\n", " etfl_model.genes.append(gene)\n", "\n", "# === 1. Define synthetic genes ===\n", "tpl_gene = Gene(\"tpl\"); tpl_gene.length_bp = 1500; tpl_gene.promoter_active = True\n", "mazE_gene = Gene(\"mazE\"); mazE_gene.length_bp = 300; mazE_gene.promoter_active = True\n", "mazF_gene = Gene(\"mazF\"); mazF_gene.length_bp = 330; mazF_gene.promoter_active = True\n", "for g in [tpl_gene, mazE_gene, mazF_gene]: safe_add_gene(g)\n", "\n", "# === 2. Add mRNA + protein metabolites ===\n", "m_tpl = get_or_add(\"m_tpl_c\", \"tpl mRNA\")\n", "m_mazE = get_or_add(\"m_mazE_c\", \"mazE mRNA\")\n", "m_mazF = get_or_add(\"m_mazF_c\", \"mazF mRNA\")\n", "p_tpl = get_or_add(\"prot_tpl_c\", \"Tpl protein\")\n", "p_mazE = get_or_add(\"prot_mazE_c\", \"MazE protein\")\n", "p_mazF = get_or_add(\"prot_mazF_c\", \"MazF protein\")\n", "\n", "# === 3. Add transcription reactions ===\n", "atp = get_or_add(\"atp_c\"); amp = get_or_add(\"amp_c\"); pi = get_or_add(\"pi_c\")\n", "ppi = get_or_add(\"ppi_c\"); h2o = get_or_add(\"h2o_c\"); h = get_or_add(\"h_c\")\n", "\n", "TX_tpl = Reaction(\"TX_tpl\", name=\"TX tpl\", lower_bound=0)\n", "TX_tpl.add_metabolites({m_tpl: 1, atp: -1500, amp: 1500, pi: 1500, h2o: -1500, h: 1500})\n", "\n", "TX_mazE = Reaction(\"TX_mazE\", name=\"TX mazE\", lower_bound=0.01)\n", "TX_mazE.add_metabolites({m_mazE: 1, atp: -300, amp: 300, pi: 300, h2o: -300, h: 300})\n", "\n", "TX_mazF = Reaction(\"TX_mazF\", name=\"TX mazF\", lower_bound=0.01)\n", "TX_mazF.add_metabolites({m_mazF: 1, atp: -330, amp: 330, pi: 330, h2o: -330, h: 330})\n", "\n", "etfl_model.add_reactions([TX_tpl, TX_mazE, TX_mazF])\n", "\n", "# === 4. Translation reactions ===\n", "gtp = get_or_add(\"gtp_c\")\n", "aa = get_or_add(\"aa_c\", \"Generic amino acid pool\")\n", "\n", "TL_tpl = Reaction(\"TL_tpl\", name=\"TL tpl\", lower_bound=0)\n", "TL_tpl.add_metabolites({aa: -500, atp: -500, gtp: -1000, h2o: 499, p_tpl: 1})\n", "\n", "TL_mazE = Reaction(\"TL_mazE\", name=\"TL mazE\", lower_bound=0)\n", "TL_mazE.add_metabolites({aa: -100, atp: -100, gtp: -200, h2o: 99, p_mazE: 1})\n", "\n", "TL_mazF = Reaction(\"TL_mazF\", name=\"TL mazF\", lower_bound=0)\n", "TL_mazF.add_metabolites({aa: -110, atp: -110, gtp: -220, h2o: 109, p_mazF: 1})\n", "\n", "etfl_model.add_reactions([TL_tpl, TL_mazE, TL_mazF])\n", "\n", "# === 5. TPL reaction: catechol + ala → L-DOPA + phenol ===\n", "ala = get_or_add(\"ala__L_c\")\n", "catechol = get_or_add(\"catechol_c\", \"Catechol\")\n", "ldopa = get_or_add(\"L_DOPA_c\", \"L-DOPA\")\n", "phenol = get_or_add(\"phenol_c\", \"Phenol\")\n", "\n", "rxn_tpl = Reaction(\"TPL\", name=\"Catechol → L-DOPA\", lower_bound=0, upper_bound=1000)\n", "rxn_tpl.add_metabolites({catechol: -1, ala: -1, ldopa: 1, phenol: 1, p_tpl: -1/65})\n", "etfl_model.add_reactions([rxn_tpl])\n", "\n", "# === 6. Exchange for secretion ===\n", "ldopa_e = get_or_add(\"L_DOPA_e\", c=\"e\")\n", "phenol_e = get_or_add(\"phenol_e\", c=\"e\")\n", "\n", "EX_ldopa = Reaction(\"EX_L_DOPA_e\", lower_bound=0, upper_bound=1000)\n", "EX_ldopa.add_metabolites({ldopa: -1, ldopa_e: 1})\n", "EX_phenol = Reaction(\"EX_phenol_e\", lower_bound=0, upper_bound=1000)\n", "EX_phenol.add_metabolites({phenol: -1, phenol_e: 1})\n", "etfl_model.add_reactions([EX_ldopa, EX_phenol])\n", "\n", "# === 7. mRNA pooling and MazF cleavage ===\n", "mRNA_pool = get_or_add(\"mRNA_pool_c\", \"mRNA pool\")\n", "\n", "for met in [m_tpl, m_mazE, m_mazF]:\n", " rxn = Reaction(f\"merge_{met.id}\", lower_bound=0, upper_bound=1000)\n", " rxn.add_metabolites({met: -1.0, mRNA_pool: 1.0})\n", " etfl_model.add_reactions([rxn])\n", "\n", "mazf_cleave = Reaction(\"MAZF_cleavage\", lower_bound=0.0, upper_bound=0.0)\n", "mazf_cleave.add_metabolites({mRNA_pool: -1.0, atp: -1.0, amp: 1.0, ppi: 1.0})\n", "etfl_model.add_reactions([mazf_cleave])\n", "\n", "# === 8. Knock out native catechol degradation ===\n", "for rxn in list(etfl_model.reactions):\n", " if catechol in rxn.metabolites and rxn.id != \"TPL\" and not rxn.id.startswith(\"EX_\"):\n", " rxn.lower_bound = 0.0\n", " rxn.upper_bound = 0.0\n", "\n", "print(\"✅ ETFL synthetic module ready.\")\n", "print(\"Added:\", [r.id for r in [TX_tpl, TL_tpl, rxn_tpl, mazf_cleave]])\n" ] }, { "cell_type": "code", "execution_count": 79, "id": "a620d12b-6469-4057-85e4-ff9a039fd4f4", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Total TX reactions added: 4068\n", "Total TL reactions added: 4068\n" ] } ], "source": [ "# === Cell 6: Add transcription & translation reactions for all genes (ETFL/COBRA layer) ===\n", "from cobra import Reaction, Metabolite\n", "\n", "# ---- helpers (safe if redefined) ----\n", "def get_or_add(mid, name, c=\"c\"):\n", " try:\n", " return etfl_model.metabolites.get_by_id(mid)\n", " except KeyError:\n", " m = Metabolite(mid, name=name, compartment=c)\n", " etfl_model.add_metabolites([m])\n", " return m\n", "\n", "def add_rna_species(gid, nt_len):\n", " m = get_or_add(f\"m_{gid}\", f\"{gid} mRNA\", \"c\")\n", " m.notes[\"nt_len\"] = int(nt_len)\n", " return m\n", "\n", "def add_protein_species(gid, aa_len, aa_comp=None):\n", " p = get_or_add(f\"prot_{gid}\", f\"{gid} protein\", \"c\")\n", " p.notes[\"aa_len\"] = int(aa_len)\n", " if aa_comp:\n", " p.notes[\"aa_counts\"] = {k:int(v) for k,v in aa_comp.items()}\n", " return p\n", "\n", "# currency metabolites (reuse if present)\n", "ATP = get_or_add(\"atp_c\",\"ATP\"); AMP = get_or_add(\"amp_c\",\"AMP\"); PI = get_or_add(\"pi_c\",\"Pi\")\n", "GTP = get_or_add(\"gtp_c\",\"GTP\"); GDP = get_or_add(\"gdp_c\",\"GDP\")\n", "H2O = get_or_add(\"h2o_c\",\"H2O\"); H = get_or_add(\"h_c\",\"H+\")\n", "AA = get_or_add(\"aa_c\",\"Amino acid pool\")\n", "tU = get_or_add(\"tRNA_uncharged_c\",\"tRNA uncharged\")\n", "tC = get_or_add(\"tRNA_charged_c\",\"tRNA charged\")\n", "\n", "RNAP_complex = get_or_add(\"RNAP_complex\",\"RNA polymerase complex\")\n", "Ribosome_complex = get_or_add(\"Ribosome_complex\",\"Ribosome complex\")\n", "\n", "# ---- add TX/TL reactions per gene (protein-coding only) ----\n", "def add_TX_TL_for_gene(gid, nt_len, aa_len):\n", " # TX: DNA template (implicit) + NTP → mRNA + energy burn (we lump NTP as ATP equivalents)\n", " tx_id = f\"TX_{gid}\"\n", " if tx_id not in etfl_model.reactions:\n", " tx = Reaction(tx_id)\n", " tx.name = f\"Transcription of {gid}\"\n", " tx.lower_bound = 0.0\n", " tx.upper_bound = 1000.0\n", " mRNA = get_or_add(f\"m_{gid}\", f\"{gid} mRNA\")\n", " # produce one mRNA; pay nt_len “ATP→AMP+Pi” and produce H+\n", " tx.add_metabolites({\n", " mRNA : +1.0,\n", " ATP : -float(nt_len),\n", " AMP : +float(nt_len),\n", " PI : +float(nt_len),\n", " H2O : -float(nt_len), # optional hydration bookkeeping\n", " H : +float(nt_len)\n", " })\n", " # couple to RNAP complex via assembly already accounted in Cell 5 (complex + CF reactions)\n", " etfl_model.add_reactions([tx])\n", "\n", " # TL: 1 mRNA + aa_len charged tRNAs + 2*aa_len GTP + aa_len H2O → 1 protein + aa_len uncharged tRNA + aa_len H+\n", " tl_id = f\"TL_{gid}\"\n", " if tl_id not in etfl_model.reactions:\n", " tl = Reaction(tl_id)\n", " tl.name = f\"Translation of {gid}\"\n", " tl.lower_bound = 0.0\n", " tl.upper_bound = 1000.0\n", " mRNA = get_or_add(f\"m_{gid}\", f\"{gid} mRNA\")\n", " PROT = get_or_add(f\"prot_{gid}\", f\"{gid} protein\")\n", " aaL = float(aa_len)\n", " tl.add_metabolites({\n", " mRNA : -1.0,\n", " PROT : +1.0,\n", " AA : -aaL, # amino acids consumed (pool)\n", " tC : -aaL, # charged tRNA consumed\n", " tU : +aaL, # uncharged tRNA released\n", " GTP : -2.0*aaL, # elongation (EF-Tu + EF-G)\n", " GDP : +2.0*aaL,\n", " H2O : -aaL, # peptide bond condensation water\n", " H : +aaL\n", " })\n", " # ribosome usage is represented by the pre-built Ribosome_complex and CF reactions\n", " etfl_model.add_reactions([tl])\n", "\n", "# Build TX/TL for all protein-coding genes from parsed genome\n", "n_tx = n_tl = 0\n", "for gid, info in gene_info.items():\n", " aa_len = int(info.get(\"aa_len\", 0) or 0)\n", " if aa_len <= 0:\n", " continue # non-coding / pseudogenes skipped for TL\n", " nt_len = int(info.get(\"nt_len\", aa_len*3) or aa_len*3)\n", " # ensure species exist (also stores lengths in notes)\n", " add_rna_species(gid, nt_len)\n", " add_protein_species(gid, aa_len, info.get(\"aa_counts\"))\n", " # add TX/TL reactions\n", " add_TX_TL_for_gene(gid, nt_len, aa_len)\n", " n_tx += 1; n_tl += 1\n", "\n", "print(f\"Total TX reactions added: {sum(1 for r in etfl_model.reactions if r.id.startswith('TX_'))}\")\n", "print(f\"Total TL reactions added: {sum(1 for r in etfl_model.reactions if r.id.startswith('TL_'))}\")\n", "\n", "# keep CPLEX explicitly (optional here but harmless)\n", "etfl_model.solver = \"cplex\"\n" ] }, { "cell_type": "code", "execution_count": 80, "id": "10f4efeb-4417-404d-ba9b-35906e6b8231", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "[6b] Adding TPL & LuxI with literature kcat values…\n", " TPL/LuxI reactions present and annotated with kcat.\n", "\n", "[6c] Building ribosome/RNAP protein compositions from genome annotation…\n", " ribosomal proteins used: 43 | RNAP proteins used: 7\n", "\n", "[7] Applying GECKO-style coupling (conservative kcat by EC; σ = 0.5)…\n", " coupled 2 reactions to their proteins (GECKO-style, σ=0.5).\n", "\n", "✅ Cell 7 complete.\n" ] } ], "source": [ "# === Cell 7: Literature-anchored enzymes (TPL/LuxI), ribosome/RNAP compositions, GECKO-style coupling ===\n", "from cobra import Reaction, Metabolite\n", "import re, math\n", "\n", "# -------------------- helpers --------------------\n", "def get_or_add(mid, name, c=\"c\"):\n", " try:\n", " return etfl_model.metabolites.get_by_id(mid)\n", " except KeyError:\n", " m = Metabolite(mid, name=name, compartment=c)\n", " etfl_model.add_metabolites([m])\n", " return m\n", "\n", "def add_rna_if_needed(gid, nt_len):\n", " m = get_or_add(f\"m_{gid}\", f\"{gid} mRNA\", \"c\")\n", " m.notes[\"nt_len\"] = int(nt_len)\n", " return m\n", "\n", "def add_protein_if_needed(gid, aa_len, aa_counts=None):\n", " p = get_or_add(f\"prot_{gid}\", f\"{gid} protein\", \"c\")\n", " p.notes[\"aa_len\"] = int(aa_len)\n", " if aa_counts:\n", " p.notes[\"aa_counts\"] = {k:int(v) for k,v in aa_counts.items()}\n", " return p\n", "\n", "def is_boundary_rxn(r):\n", " return r.id.startswith((\"EX_\", \"DM_\", \"SK_\")) or getattr(r, \"boundary\", False)\n", "\n", "# currency metabolites\n", "ATP = get_or_add(\"atp_c\",\"ATP\"); ADP = get_or_add(\"adp_c\",\"ADP\"); PI = get_or_add(\"pi_c\",\"Pi\")\n", "AMP = get_or_add(\"amp_c\",\"AMP\"); PPi = get_or_add(\"ppi_c\",\"PPi\")\n", "GTP = get_or_add(\"gtp_c\",\"GTP\"); GDP = get_or_add(\"gdp_c\",\"GDP\")\n", "H2O = get_or_add(\"h2o_c\",\"H2O\"); H = get_or_add(\"h_c\",\"H+\")\n", "\n", "print(\"\\n[6b] Adding TPL & LuxI with literature kcat values…\")\n", "\n", "# === TPL Reaction ===\n", "catechol = get_or_add(\"catechol_c\",\"Catechol\")\n", "pyr = get_or_add(\"pyr_c\",\"Pyruvate\")\n", "nh4 = get_or_add(\"nh4_c\",\"Ammonium\")\n", "ldopa = get_or_add(\"ldopa_c\",\"L-3,4-dihydroxy-L-phenylalanine\")\n", "\n", "if \"TPL\" not in etfl_model.reactions:\n", " tpl = Reaction(\"TPL\"); tpl.name = \"Tyrosine phenol-lyase L-DOPA synthesis\"\n", " tpl.lower_bound = 0.0; tpl.upper_bound = 1000.0\n", " tpl.add_metabolites({catechol:-1.0, pyr:-1.0, nh4:-1.0, ldopa:+1.0, H2O:+1.0})\n", " etfl_model.add_reactions([tpl])\n", "else:\n", " tpl = etfl_model.reactions.get_by_id(\"TPL\")\n", "\n", "tpl_kcat = 10.0\n", "tpl.notes[\"kcat_lit_s^-1\"] = tpl_kcat\n", "tpl_gid = \"tpl\"\n", "add_rna_if_needed(tpl_gid, 1500); add_protein_if_needed(tpl_gid, 500)\n", "\n", "# === AHL_SYN Reaction (LuxI) ===\n", "ahl = get_or_add(\"ahl_c\",\"AHL signal\")\n", "mta = get_or_add(\"mta_c\",\"5'-Methylthioadenosine\")\n", "sam = get_or_add(\"amet_c\",\"S-adenosylmethionine\")\n", "\n", "if \"AHL_SYN\" not in etfl_model.reactions:\n", " ahl_syn = Reaction(\"AHL_SYN\"); ahl_syn.name = \"AHL synthase (LuxI)\"\n", " ahl_syn.lower_bound = 0.0; ahl_syn.upper_bound = 1000.0\n", " ahl_syn.add_metabolites({sam:-1.0, ahl:+1.0, mta:+1.0})\n", " etfl_model.add_reactions([ahl_syn])\n", "else:\n", " ahl_syn = etfl_model.reactions.get_by_id(\"AHL_SYN\")\n", "\n", "luxI_kcat = 1.0\n", "ahl_syn.notes[\"kcat_lit_s^-1\"] = luxI_kcat\n", "luxI_gid = \"luxI\"\n", "add_rna_if_needed(luxI_gid, 600); add_protein_if_needed(luxI_gid, 200)\n", "\n", "print(\" TPL/LuxI reactions present and annotated with kcat.\")\n", "\n", "# === Ribosome & RNAP Setup ===\n", "print(\"\\n[6c] Building ribosome/RNAP protein compositions from genome annotation…\")\n", "rnap_subunits = [g for g in gene_info if g.lower().startswith(\"rpo\")] or list(rnap_genes)\n", "ribosomal_subunits = [g for g in gene_info if re.match(r\"rp[sl][A-Za-z0-9_]+\", g)] or list(ribosomal_genes)\n", "\n", "rib_comp = {f\"prot_{gid}\":1 for gid in ribosomal_subunits if f\"prot_{gid}\" in etfl_model.metabolites}\n", "rnap_comp = {f\"prot_{gid}\":1 for gid in rnap_subunits if f\"prot_{gid}\" in etfl_model.metabolites}\n", "\n", "etfl_model._ribosome_protein_comp = rib_comp\n", "etfl_model._rnap_protein_comp = rnap_comp\n", "print(f\" ribosomal proteins used: {len(rib_comp)} | RNAP proteins used: {len(rnap_comp)}\")\n", "\n", "# === GECKO-Style Enzyme Coupling ===\n", "print(\"\\n[7] Applying GECKO-style coupling (conservative kcat by EC; σ = 0.5)…\")\n", "\n", "ec_kcat_table = {\"1\":40.0,\"2\":35.0,\"3\":30.0,\"4\":20.0,\"5\":15.0,\"6\":10.0}\n", "default_kcat = 20.0\n", "sigma = 0.5\n", "rxn_to_ec = {rxn.id: rxn.notes.get(\"ec-code\") or rxn.annotation.get(\"ec-code\") or rxn.annotation.get(\"ec\") for rxn in etfl_model.reactions}\n", "\n", "def kcat_for_rxn(rid):\n", " ec = rxn_to_ec.get(rid)\n", " if not ec: return default_kcat\n", " if isinstance(ec, list): ec = ec[0]\n", " for key in (ec, \".\".join(ec.split(\".\")[:3]), ec.split(\".\")[0]):\n", " if key in ec_kcat_table: return ec_kcat_table[key]\n", " return default_kcat\n", "\n", "def couple_rxn_to_protein(rxn, pal_gid, kcat_s):\n", " pid = f\"prot_{pal_gid}\"\n", " if pid not in etfl_model.metabolites or is_boundary_rxn(rxn): return False\n", " coeff = -1.0 / max(kcat_s * sigma, 1e-9)\n", " rxn.add_metabolites({etfl_model.metabolites.get_by_id(pid): coeff}, combine=True)\n", " return True\n", "\n", "# Explicit coupling\n", "coupled = 0\n", "if couple_rxn_to_protein(tpl, tpl_gid, tpl_kcat): coupled += 1\n", "if couple_rxn_to_protein(ahl_syn, luxI_gid, luxI_kcat): coupled += 1\n", "\n", "# Autocouple mono-gene reactions\n", "for rxn in etfl_model.reactions:\n", " gpr = rxn.gene_reaction_rule\n", " if not gpr or \" or \" in gpr or \" and \" in gpr: continue\n", " pal_gid = name_map.get(gpr.strip())\n", " if pal_gid and couple_rxn_to_protein(rxn, pal_gid, kcat_for_rxn(rxn.id)): coupled += 1\n", "\n", "print(f\" coupled {coupled} reactions to their proteins (GECKO-style, σ={sigma}).\")\n", "etfl_model.solver = \"cplex\"\n", "print(\"\\n✅ Cell 7 complete.\")\n" ] }, { "cell_type": "code", "execution_count": 81, "id": "029f5718-a12b-4582-9532-ea253abfa1e2", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[TPL] Variant = pyruvate · reaction stoichiometry set · exchanges ready.\n", "Scenarios ready: scenario_WT_no_TPL(), scenario_WT_with_TPL(), scenario_TPL_with_knockouts().\n", "Cell 8 complete ✅ — L-DOPA module configured and scenario toggles installed.\n" ] } ], "source": [ "# === Cell 8: L-DOPA module + scenario toggles (WT±TPL, TPL+knockouts) ===\n", "from cobra import Reaction, Metabolite\n", "import re\n", "\n", "# --- helpers (compatible with previous cells) ---\n", "def get_or_add(mid, name, c=\"c\"):\n", " try: return etfl_model.metabolites.get_by_id(mid)\n", " except KeyError:\n", " m = Metabolite(mid, name=name, compartment=c); etfl_model.add_metabolites([m]); return m\n", "\n", "def safe_add_rxn(rxn):\n", " if rxn.id not in etfl_model.reactions:\n", " etfl_model.add_reactions([rxn])\n", "\n", "def ensure_exchange(met_id, lb=0.0, ub=1000.0, prefix=\"EX_\"):\n", " rid = f\"{prefix}{met_id.replace('_c','_e')}\" if met_id.endswith(\"_c\") else f\"{prefix}{met_id}\"\n", " if rid in etfl_model.reactions:\n", " r = etfl_model.reactions.get_by_id(rid); r.lower_bound = min(r.lower_bound, lb); r.upper_bound = max(r.upper_bound, ub)\n", " return r\n", " m = etfl_model.metabolites.get_by_id(met_id)\n", " ex = Reaction(rid); ex.lower_bound = lb; ex.upper_bound = ub\n", " ex.add_metabolites({m:-1.0})\n", " etfl_model.add_reactions([ex])\n", " return ex\n", "\n", "# ---------------------------------------------------------------------------------\n", "# 8a) TPL module (two literature routes; choose one without clashing with Cell 7)\n", "# ---------------------------------------------------------------------------------\n", "# Variant A (used in Cell 7): catechol + pyruvate + NH4+ -> L-DOPA + H2O (reverse TPL with pyruvate as amino group acceptor)\n", "# Variant B (alternative literature): catechol + L-alanine -> L-DOPA + phenol\n", "TPL_VARIANT = \"pyruvate\" # choose: \"pyruvate\" | \"alanine\"\n", "\n", "# core metabolites\n", "catechol = get_or_add(\"catechol_c\",\"Catechol\")\n", "ldopa = get_or_add(\"ldopa_c\",\"L-3,4-dihydroxy-L-phenylalanine\")\n", "pyr = get_or_add(\"pyr_c\",\"Pyruvate\")\n", "nh4 = get_or_add(\"nh4_c\",\"Ammonium\")\n", "ala = get_or_add(\"ala__L_c\",\"L-Alanine\")\n", "phenol = get_or_add(\"phenol_c\",\"Phenol\")\n", "H2O = get_or_add(\"h2o_c\",\"H2O\")\n", "\n", "# add (or adjust) TPL reaction according to variant (keep a single rxn id \"TPL\")\n", "tpl = etfl_model.reactions.get_by_id(\"TPL\") if \"TPL\" in etfl_model.reactions else Reaction(\"TPL\")\n", "tpl.name = \"Tyrosine phenol-lyase L-DOPA synthesis\"\n", "tpl.lower_bound = 0.0; tpl.upper_bound = 1000.0\n", "# clear stoichiometry safely\n", "if \"TPL\" in etfl_model.reactions:\n", " for met in list(tpl.metabolites.keys()): tpl.add_metabolites({met: -tpl.metabolites[met]})\n", "# set stoichiometry per variant\n", "if TPL_VARIANT == \"pyruvate\":\n", " # catechol + pyruvate + NH4+ → L-DOPA + H2O (matches what we used in Cell 7)\n", " tpl.add_metabolites({catechol:-1.0, pyr:-1.0, nh4:-1.0, ldopa:+1.0, H2O:+1.0})\n", "else:\n", " # catechol + L-alanine → L-DOPA + phenol (alternative reported route)\n", " tpl.add_metabolites({catechol:-1.0, ala:-1.0, ldopa:+1.0, phenol:+1.0})\n", "\n", "safe_add_rxn(tpl)\n", "\n", "# exchanges for products (allow secretion for comparison downstream)\n", "ensure_exchange(\"ldopa_c\", lb=0.0, ub=1000.0, prefix=\"EX_\") # EX_ldopa_c or EX_ldopa_e depending on id style\n", "ensure_exchange(\"phenol_c\", lb=0.0, ub=1000.0, prefix=\"EX_\") # harmless if phenol unused (pyruvate variant)\n", "\n", "# ---------------------------------------------------------------------------------\n", "# 8b) Heterologous tpl gene lengths (only if not defined from earlier steps)\n", "# ---------------------------------------------------------------------------------\n", "if \"tpl\" not in gene_info:\n", " # If you prefer exact sequence: set tpl_length from UniProt and aa_counts via your parser\n", " tpl_length = 500 # conservative default AA length; replace with measured sequence when available\n", " gene_info[\"tpl\"] = {\"locus\":\"tpl\",\"product\":\"tyrosine phenol-lyase\",\"nt_len\":tpl_length*3,\"aa_len\":tpl_length,\"aa_counts\":{}}\n", "\n", "# ensure mRNA/protein species exist (keeps Cell 6 TX/TL complete for tpl)\n", "add_rna_if_needed(\"tpl\", gene_info[\"tpl\"][\"nt_len\"])\n", "add_protein_if_needed(\"tpl\", gene_info[\"tpl\"][\"aa_len\"], gene_info[\"tpl\"].get(\"aa_counts\"))\n", "\n", "print(f\"[TPL] Variant = {TPL_VARIANT} · reaction stoichiometry set · exchanges ready.\")\n", "\n", "# ---------------------------------------------------------------------------------\n", "# 8c) Knockout control utilities (for catechol degradative arm: catA/B/C and regulator benR)\n", "# ---------------------------------------------------------------------------------\n", "# Store original bounds so we can toggle scenarios cleanly\n", "if not hasattr(etfl_model, \"_ko_original_bounds\"):\n", " etfl_model._ko_original_bounds = {}\n", "\n", "KNOCKOUT_GENES = [\"catA\", \"catB\", \"catC\", \"benR\"]\n", "\n", "def set_knockouts(active=True, genes=KNOCKOUT_GENES):\n", " \"\"\"Toggle knockouts by zeroing reactions whose id/name/GPR mentions the gene token.\"\"\"\n", " changed = 0\n", " for rxn in etfl_model.reactions:\n", " text = f\"{rxn.id} {rxn.name} {rxn.gene_reaction_rule}\".lower()\n", " if any(g.lower() in text for g in genes):\n", " key = (rxn.id, \"lb\"), (rxn.id, \"ub\")\n", " # save once\n", " if rxn.id not in etfl_model._ko_original_bounds:\n", " etfl_model._ko_original_bounds[rxn.id] = (rxn.lower_bound, rxn.upper_bound)\n", " if active:\n", " rxn.lower_bound = 0.0; rxn.upper_bound = 0.0\n", " else:\n", " # restore\n", " lb, ub = etfl_model._ko_original_bounds.get(rxn.id, (rxn.lower_bound, rxn.upper_bound))\n", " rxn.lower_bound = lb; rxn.upper_bound = ub\n", " changed += 1\n", " state = \"ON\" if active else \"OFF\"\n", " print(f\"[KO] Knockouts {state}: matched/updated {changed} reactions for {genes}.\")\n", "\n", "def set_tpl_active(active=True):\n", " \"\"\"Enable/disable the TPL reaction (without altering coupling added in Cell 7).\"\"\"\n", " if \"TPL\" not in etfl_model.reactions:\n", " print(\"TPL reaction not found.\")\n", " return\n", " rxn = etfl_model.reactions.get_by_id(\"TPL\")\n", " if active:\n", " rxn.lower_bound = 0.0; rxn.upper_bound = 1000.0\n", " print(\"[TPL] Enabled.\")\n", " else:\n", " rxn.lower_bound = 0.0; rxn.upper_bound = 0.0\n", " print(\"[TPL] Disabled.\")\n", "\n", "# ---------------------------------------------------------------------------------\n", "# 8d) Scenario presets (for later growth / L-DOPA production analysis)\n", "# ---------------------------------------------------------------------------------\n", "def scenario_WT_no_TPL():\n", " set_tpl_active(False)\n", " set_knockouts(False)\n", "\n", "def scenario_WT_with_TPL():\n", " set_tpl_active(True)\n", " set_knockouts(False)\n", "\n", "def scenario_TPL_with_knockouts():\n", " set_tpl_active(True)\n", " set_knockouts(True)\n", "\n", "print(\"Scenarios ready: scenario_WT_no_TPL(), scenario_WT_with_TPL(), scenario_TPL_with_knockouts().\")\n", "\n", "# keep CPLEX explicit\n", "etfl_model.solver = \"cplex\"\n", "print(\"Cell 8 complete ✅ — L-DOPA module configured and scenario toggles installed.\")\n" ] }, { "cell_type": "code", "execution_count": 82, "id": "fc0d4c07-1acf-4739-8455-1e675507297f", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "MazE/MazF gene species present; TX/TL reactions ensured.\n", "mRNA merge reactions added: 0\n", "MazF cleavage reaction present (upper_bound=0 by default).\n", "Plasmid replication ATP drain present (default OFF).\n", "\n", "Toggles available:\n", " set_mazf_active(True/False) # trigger/disable kill-switch\n", " set_mazE_burden(min_TL_flux) # impose basal MazE translation burden\n", " set_plasmid_burden(True/False) # include plasmid ATP drain\n", "\n", "Cell 9 complete ✅ — MazE/MazF system installed with global mRNA pool & cleavage, plasmid burden, and scenario toggles.\n" ] } ], "source": [ "# === Cell 9: MazE/MazF system, global mRNA pool & cleavage, plasmid burden, toggles ===\n", "from cobra import Reaction, Metabolite\n", "from pathlib import Path\n", "import urllib.request as _url\n", "from Bio import SeqIO\n", "\n", "# ---------- helpers ----------\n", "def get_or_add(mid, name, c=\"c\"):\n", " try: return etfl_model.metabolites.get_by_id(mid)\n", " except KeyError:\n", " m = Metabolite(mid, name=name, compartment=c); etfl_model.add_metabolites([m]); return m\n", "\n", "def add_rna_if_needed(gid, nt_len):\n", " m = get_or_add(f\"m_{gid}\", f\"{gid} mRNA\", \"c\"); m.notes[\"nt_len\"] = int(nt_len); return m\n", "\n", "def add_protein_if_needed(gid, aa_len, aa_counts=None):\n", " p = get_or_add(f\"prot_{gid}\", f\"{gid} protein\", \"c\")\n", " p.notes[\"aa_len\"] = int(aa_len)\n", " if aa_counts: p.notes[\"aa_counts\"] = {k:int(v) for k,v in aa_counts.items()}\n", " return p\n", "\n", "def ensure_TX_TL(gid, nt_len, aa_len):\n", " # transcription\n", " tx_id = f\"TX_{gid}\"\n", " if tx_id not in etfl_model.reactions:\n", " tx = Reaction(tx_id); tx.name=f\"Transcription of {gid}\"; tx.lower_bound=0; tx.upper_bound=1000\n", " mRNA = get_or_add(f\"m_{gid}\", f\"{gid} mRNA\")\n", " tx.add_metabolites({\n", " mRNA:+1.0, ATP:-float(nt_len), AMP:+float(nt_len), PI:+float(nt_len),\n", " get_or_add(\"h2o_c\",\"H2O\"):-float(nt_len), get_or_add(\"h_c\",\"H+\"):+float(nt_len)\n", " })\n", " etfl_model.add_reactions([tx])\n", " # translation\n", " tl_id = f\"TL_{gid}\"\n", " if tl_id not in etfl_model.reactions:\n", " tl = Reaction(tl_id); tl.name=f\"Translation of {gid}\"; tl.lower_bound=0; tl.upper_bound=1000\n", " AA = get_or_add(\"aa_c\",\"Amino acid pool\"); tU = get_or_add(\"tRNA_uncharged_c\",\"tRNA uncharged\")\n", " tC = get_or_add(\"tRNA_charged_c\",\"tRNA charged\"); GTP=get_or_add(\"gtp_c\",\"GTP\"); GDP=get_or_add(\"gdp_c\",\"GDP\")\n", " mRNA= get_or_add(f\"m_{gid}\", f\"{gid} mRNA\"); PROT=get_or_add(f\"prot_{gid}\", f\"{gid} protein\")\n", " aaL = float(aa_len)\n", " tl.add_metabolites({mRNA:-1.0, PROT:+1.0, AA:-aaL, tC:-aaL, tU:+aaL, GTP:-2.0*aaL, GDP:+2.0*aaL,\n", " get_or_add(\"h2o_c\",\"H2O\"):-aaL, get_or_add(\"h_c\",\"H+\"):+aaL})\n", " etfl_model.add_reactions([tl])\n", "\n", "# ---------- 9a) Download / add MazE/MazF sequences (E. coli K-12) if needed ----------\n", "MAZE_FASTA = DATA / \"maze_uniprot.fasta\"\n", "MAZF_FASTA = DATA / \"mazf_uniprot.fasta\"\n", "if not MAZE_FASTA.exists():\n", " print(\"Downloading MazE (E. coli) from UniProt…\")\n", " _url.urlretrieve(\"https://rest.uniprot.org/uniprotkb/P60723.fasta\", MAZE_FASTA)\n", "if not MAZF_FASTA.exists():\n", " print(\"Downloading MazF (E. coli) from UniProt…\")\n", " _url.urlretrieve(\"https://rest.uniprot.org/uniprotkb/P60724.fasta\", MAZF_FASTA)\n", "\n", "maze_seq = str(next(SeqIO.parse(str(MAZE_FASTA), \"fasta\")).seq)\n", "mazf_seq = str(next(SeqIO.parse(str(MAZF_FASTA), \"fasta\")).seq)\n", "maze_len = len(maze_seq); mazf_len = len(mazf_seq)\n", "\n", "# register in gene_info (allows Cell 6 TX/TL helpers to work)\n", "if \"mazE\" not in gene_info:\n", " gene_info[\"mazE\"] = {\"locus\":\"mazE\",\"product\":\"MazE antitoxin\",\"nt_len\":maze_len*3,\"aa_len\":maze_len,\"aa_counts\":None}\n", "if \"mazF\" not in gene_info:\n", " gene_info[\"mazF\"] = {\"locus\":\"mazF\",\"product\":\"MazF toxin endoribonuclease\",\"nt_len\":mazf_len*3,\"aa_len\":mazf_len,\"aa_counts\":None}\n", "\n", "# ensure species + TX/TL exist\n", "add_rna_if_needed(\"mazE\", gene_info[\"mazE\"][\"nt_len\"])\n", "add_protein_if_needed(\"mazE\", gene_info[\"mazE\"][\"aa_len\"])\n", "ensure_TX_TL(\"mazE\", gene_info[\"mazE\"][\"nt_len\"], gene_info[\"mazE\"][\"aa_len\"])\n", "\n", "add_rna_if_needed(\"mazF\", gene_info[\"mazF\"][\"nt_len\"])\n", "add_protein_if_needed(\"mazF\", gene_info[\"mazF\"][\"aa_len\"])\n", "ensure_TX_TL(\"mazF\", gene_info[\"mazF\"][\"nt_len\"], gene_info[\"mazF\"][\"aa_len\"])\n", "\n", "print(\"MazE/MazF gene species present; TX/TL reactions ensured.\")\n", "\n", "# ---------- 9b) Global mRNA pool and MazF-induced cleavage ----------\n", "# Literature: MazF cleaves mRNA at ACA motifs → global loss of transcripts and growth arrest.\n", "# Model: sum all mRNAs into mRNA_pool, then allow a MazF cleavage drain that consumes 1 mRNA equivalent and a small ATP for cleanup.\n", "mRNA_pool = get_or_add(\"mRNA_pool_c\", \"mRNA pool\", \"c\")\n", "\n", "# merge reactions: m_gid -> mRNA_pool (this can be large; but you asked for full realism)\n", "merge_added = 0\n", "for gid, info in gene_info.items():\n", " mid = f\"m_{gid}\"\n", " if mid in [m.id for m in etfl_model.metabolites]:\n", " rid = f\"MRG_{mid}\"\n", " if rid not in etfl_model.reactions:\n", " r = Reaction(rid); r.lower_bound=0; r.upper_bound=1000\n", " r.add_metabolites({ etfl_model.metabolites.get_by_id(mid): -1.0, mRNA_pool: +1.0 })\n", " etfl_model.add_reactions([r]); merge_added += 1\n", "# include heterologous mRNAs explicitly\n", "for mid in (\"m_tpl\",\"m_mazE\",\"m_mazF\"):\n", " if mid in [m.id for m in etfl_model.metabolites] and f\"MRG_{mid}\" not in etfl_model.reactions:\n", " r = Reaction(f\"MRG_{mid}\"); r.lower_bound=0; r.upper_bound=1000\n", " r.add_metabolites({ etfl_model.metabolites.get_by_id(mid): -1.0, mRNA_pool: +1.0 })\n", " etfl_model.add_reactions([r]); merge_added += 1\n", "print(f\"mRNA merge reactions added: {merge_added}\")\n", "\n", "# MazF cleavage (initially OFF)\n", "if \"MAZF_cleavage\" not in etfl_model.reactions:\n", " mazf_cleave = Reaction(\"MAZF_cleavage\"); mazf_cleave.lower_bound=0.0; mazf_cleave.upper_bound=0.0\n", " mazf_cleave.name = \"MazF-mediated global mRNA cleavage\"\n", " mazf_cleave.add_metabolites({\n", " mRNA_pool : -1.0,\n", " get_or_add(\"atp_c\",\"ATP\") : -1.0,\n", " get_or_add(\"adp_c\",\"ADP\") : +1.0,\n", " get_or_add(\"pi_c\",\"Pi\") : +1.0\n", " })\n", " etfl_model.add_reactions([mazf_cleave])\n", "print(\"MazF cleavage reaction present (upper_bound=0 by default).\")\n", "\n", "# ---------- 9c) Plasmid replication burden (ATP drain) ----------\n", "# 50 kb plasmid × 20 copies → ~1e6 ATP per division; we model as a drain that you can enable in scenarios.\n", "plasmid_bp = 50_000\n", "copy_number = 20\n", "ATP = get_or_add(\"atp_c\",\"ATP\"); AMP = get_or_add(\"amp_c\",\"AMP\"); PI = get_or_add(\"pi_c\",\"Pi\")\n", "\n", "if \"PLASMID_replication\" not in etfl_model.reactions:\n", " plasmid_rep = Reaction(\"PLASMID_replication\")\n", " plasmid_rep.lower_bound = 0.0; plasmid_rep.upper_bound = 0.0 # OFF by default; toggle in scenarios\n", " plasmid_rep.add_metabolites({\n", " ATP: -plasmid_bp*copy_number,\n", " AMP: +plasmid_bp*copy_number,\n", " PI : +plasmid_bp*copy_number\n", " })\n", " etfl_model.add_reactions([plasmid_rep])\n", "print(\"Plasmid replication ATP drain present (default OFF).\")\n", "\n", "# ---------- 9d) Scenario toggles for kill-switch experiments ----------\n", "def set_mazf_active(active: bool):\n", " \"\"\"Turn MazF cleavage ON/OFF by changing UB of MAZF_cleavage.\"\"\"\n", " r = etfl_model.reactions.get_by_id(\"MAZF_cleavage\")\n", " r.upper_bound = 1000.0 if active else 0.0\n", " print(f\"[MazF] cleavage {'ON' if active else 'OFF'} (UB={r.upper_bound}).\")\n", "\n", "def set_mazE_burden(min_TL_flux: float = 0.0):\n", " \"\"\"Impose a basal translation burden for MazE (mmol gDW⁻¹ h⁻¹) via TL_mazE lower bound.\"\"\"\n", " rid = \"TL_mazE\"\n", " if rid not in etfl_model.reactions:\n", " print(\"TL_mazE not found; ensure Cell 6 created TX/TL for mazE.\")\n", " return\n", " r = etfl_model.reactions.get_by_id(rid)\n", " r.lower_bound = max(0.0, float(min_TL_flux))\n", " print(f\"[MazE] constitutive TL burden set: LB(TL_mazE) = {r.lower_bound}.\")\n", "\n", "def set_plasmid_burden(active: bool):\n", " \"\"\"Toggle ATP drain for plasmid replication.\"\"\"\n", " r = etfl_model.reactions.get_by_id(\"PLASMID_replication\")\n", " if active:\n", " r.upper_bound = 1000.0\n", " print(\"[Plasmid] replication burden ON (ATP drain enabled).\")\n", " else:\n", " r.lower_bound = 0.0; r.upper_bound = 0.0\n", " print(\"[Plasmid] replication burden OFF.\")\n", "\n", "print(\"\\nToggles available:\")\n", "print(\" set_mazf_active(True/False) # trigger/disable kill-switch\")\n", "print(\" set_mazE_burden(min_TL_flux) # impose basal MazE translation burden\")\n", "print(\" set_plasmid_burden(True/False) # include plasmid ATP drain\")\n", "\n", "# keep CPLEX explicit\n", "etfl_model.solver = \"cplex\"\n", "print(\"\\nCell 9 complete ✅ — MazE/MazF system installed with global mRNA pool & cleavage, plasmid burden, and scenario toggles.\")\n" ] }, { "cell_type": "code", "execution_count": 83, "id": "eb9df8a6-3cce-440c-9616-325ac31b9978", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "QS params set: {'K': 0.5, 'n': 2.0, 'w_base': 0.0, 'w_max': 1.0}\n", "✅ Cell 10 complete — LuxI/R expression ensured, AHL handling + Hill dynamics in place.\n" ] } ], "source": [ "# === Cell 10: Quorum Sensing (LuxI/LuxR · AHL dynamics · Hill params) ===\n", "from cobra import Reaction, Metabolite\n", "\n", "# helper\n", "def get_or_add(mid, name, c=\"c\"):\n", " try: return etfl_model.metabolites.get_by_id(mid)\n", " except KeyError:\n", " m = Metabolite(mid, name=name, compartment=c)\n", " etfl_model.add_metabolites([m])\n", " return m\n", "\n", "# 10a) AHL metabolite, exchange, degradation\n", "AHL = get_or_add(\"ahl_c\", \"Acyl-homoserine lactone (QS signal)\")\n", "if \"EX_ahl_c\" not in etfl_model.reactions:\n", " EX_AHL = Reaction(\"EX_ahl_c\"); EX_AHL.lower_bound = 0.0; EX_AHL.upper_bound = 1000.0\n", " EX_AHL.add_metabolites({AHL: -1.0}); etfl_model.add_reactions([EX_AHL])\n", "if \"AHL_deg\" not in etfl_model.reactions:\n", " AHL_deg = Reaction(\"AHL_deg\"); AHL_deg.lower_bound = 0.0; AHL_deg.upper_bound = 1000.0\n", " AHL_deg.add_metabolites({AHL: -1.0}); etfl_model.add_reactions([AHL_deg])\n", "\n", "# 10b) LuxI/LuxR TX/TL and burden\n", "if \"luxI\" not in gene_info:\n", " gene_info[\"luxI\"] = {\"locus\":\"luxI\",\"product\":\"LuxI\",\"nt_len\":600,\"aa_len\":200,\"aa_counts\":None}\n", "if \"luxR\" not in gene_info:\n", " gene_info[\"luxR\"] = {\"locus\":\"luxR\",\"product\":\"LuxR\",\"nt_len\":720,\"aa_len\":240,\"aa_counts\":None}\n", "\n", "def ensure_TX_TL(gid, nt_len, aa_len):\n", " # TX\n", " tx_id = f\"TX_{gid}\"\n", " if tx_id not in etfl_model.reactions:\n", " tx = Reaction(tx_id); tx.lower_bound = 0; tx.upper_bound = 1000\n", " m = get_or_add(f\"m_{gid}\", f\"{gid} mRNA\")\n", " tx.add_metabolites({m:+1, ATP:-nt_len, AMP:+nt_len, PI:+nt_len,\n", " H2O:-nt_len, H:+nt_len})\n", " etfl_model.add_reactions([tx])\n", " # TL\n", " tl_id = f\"TL_{gid}\"\n", " if tl_id not in etfl_model.reactions:\n", " tl = Reaction(tl_id); tl.lower_bound = 0; tl.upper_bound = 1000\n", " m = get_or_add(f\"m_{gid}\", f\"{gid} mRNA\")\n", " p = get_or_add(f\"prot_{gid}\", f\"{gid} protein\")\n", " aaL = float(aa_len)\n", " AA = get_or_add(\"aa_c\",\"Amino acid pool\"); tU = get_or_add(\"tRNA_uncharged_c\",\"tRNA uncharged\")\n", " tC = get_or_add(\"tRNA_charged_c\",\"tRNA charged\"); GTP = get_or_add(\"gtp_c\",\"GTP\"); GDP = get_or_add(\"gdp_c\",\"GDP\")\n", " tl.add_metabolites({m:-1, p:+1, AA:-aaL, tC:-aaL, tU:+aaL, GTP:-2*aaL, GDP:+2*aaL, H2O:-aaL, H:+aaL})\n", " etfl_model.add_reactions([tl])\n", "\n", "# Ensure both are expressed\n", "for gid in (\"luxI\",\"luxR\"):\n", " ensure_TX_TL(gid, gene_info[gid][\"nt_len\"], gene_info[gid][\"aa_len\"])\n", " get_or_add(f\"m_{gid}\", f\"{gid} mRNA\")\n", " get_or_add(f\"prot_{gid}\", f\"{gid} protein\")\n", "\n", "# 10c) QS Hill dynamics\n", "etfl_model._qs_params = {\n", " \"K\": 0.5,\n", " \"n\": 2.0,\n", " \"w_base\": 0.0,\n", " \"w_max\": 1.0\n", "}\n", "print(\"QS params set:\", etfl_model._qs_params)\n", "etfl_model.solver = \"cplex\"\n", "print(\"✅ Cell 10 complete — LuxI/R expression ensured, AHL handling + Hill dynamics in place.\")\n" ] }, { "cell_type": "code", "execution_count": 84, "id": "3567f9ee-c59d-4085-8e55-1b1ea4af2575", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "QS params set: {'K': 0.5, 'n': 2.0, 'w_base': 0.0, 'w_max': 1.0}\n", "✅ Cell 10 complete — LuxI/R expression ensured, AHL handling + Hill dynamics in place.\n" ] } ], "source": [ "# === Cell 10: Quorum Sensing (LuxI/LuxR · AHL dynamics · Hill params) ===\n", "from cobra import Reaction, Metabolite\n", "\n", "# helper\n", "def get_or_add(mid, name, c=\"c\"):\n", " try: return etfl_model.metabolites.get_by_id(mid)\n", " except KeyError:\n", " m = Metabolite(mid, name=name, compartment=c)\n", " etfl_model.add_metabolites([m])\n", " return m\n", "\n", "# 10a) AHL metabolite, exchange, degradation\n", "AHL = get_or_add(\"ahl_c\", \"Acyl-homoserine lactone (QS signal)\")\n", "if \"EX_ahl_c\" not in etfl_model.reactions:\n", " EX_AHL = Reaction(\"EX_ahl_c\"); EX_AHL.lower_bound = 0.0; EX_AHL.upper_bound = 1000.0\n", " EX_AHL.add_metabolites({AHL: -1.0}); etfl_model.add_reactions([EX_AHL])\n", "if \"AHL_deg\" not in etfl_model.reactions:\n", " AHL_deg = Reaction(\"AHL_deg\"); AHL_deg.lower_bound = 0.0; AHL_deg.upper_bound = 1000.0\n", " AHL_deg.add_metabolites({AHL: -1.0}); etfl_model.add_reactions([AHL_deg])\n", "\n", "# 10b) LuxI/LuxR TX/TL and burden\n", "if \"luxI\" not in gene_info:\n", " gene_info[\"luxI\"] = {\"locus\":\"luxI\",\"product\":\"LuxI\",\"nt_len\":600,\"aa_len\":200,\"aa_counts\":None}\n", "if \"luxR\" not in gene_info:\n", " gene_info[\"luxR\"] = {\"locus\":\"luxR\",\"product\":\"LuxR\",\"nt_len\":720,\"aa_len\":240,\"aa_counts\":None}\n", "\n", "def ensure_TX_TL(gid, nt_len, aa_len):\n", " # TX\n", " tx_id = f\"TX_{gid}\"\n", " if tx_id not in etfl_model.reactions:\n", " tx = Reaction(tx_id); tx.lower_bound = 0; tx.upper_bound = 1000\n", " m = get_or_add(f\"m_{gid}\", f\"{gid} mRNA\")\n", " tx.add_metabolites({m:+1, ATP:-nt_len, AMP:+nt_len, PI:+nt_len,\n", " H2O:-nt_len, H:+nt_len})\n", " etfl_model.add_reactions([tx])\n", " # TL\n", " tl_id = f\"TL_{gid}\"\n", " if tl_id not in etfl_model.reactions:\n", " tl = Reaction(tl_id); tl.lower_bound = 0; tl.upper_bound = 1000\n", " m = get_or_add(f\"m_{gid}\", f\"{gid} mRNA\")\n", " p = get_or_add(f\"prot_{gid}\", f\"{gid} protein\")\n", " aaL = float(aa_len)\n", " AA = get_or_add(\"aa_c\",\"Amino acid pool\"); tU = get_or_add(\"tRNA_uncharged_c\",\"tRNA uncharged\")\n", " tC = get_or_add(\"tRNA_charged_c\",\"tRNA charged\"); GTP = get_or_add(\"gtp_c\",\"GTP\"); GDP = get_or_add(\"gdp_c\",\"GDP\")\n", " tl.add_metabolites({m:-1, p:+1, AA:-aaL, tC:-aaL, tU:+aaL, GTP:-2*aaL, GDP:+2*aaL, H2O:-aaL, H:+aaL})\n", " etfl_model.add_reactions([tl])\n", "\n", "# Ensure both are expressed\n", "for gid in (\"luxI\",\"luxR\"):\n", " ensure_TX_TL(gid, gene_info[gid][\"nt_len\"], gene_info[gid][\"aa_len\"])\n", " get_or_add(f\"m_{gid}\", f\"{gid} mRNA\")\n", " get_or_add(f\"prot_{gid}\", f\"{gid} protein\")\n", "\n", "# 10c) QS Hill dynamics\n", "etfl_model._qs_params = {\n", " \"K\": 0.5,\n", " \"n\": 2.0,\n", " \"w_base\": 0.0,\n", " \"w_max\": 1.0\n", "}\n", "print(\"QS params set:\", etfl_model._qs_params)\n", "etfl_model.solver = \"cplex\"\n", "print(\"✅ Cell 10 complete — LuxI/R expression ensured, AHL handling + Hill dynamics in place.\")\n" ] }, { "cell_type": "code", "execution_count": 85, "id": "657b51d7-4f5a-4ae5-9d42-67697c763123", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Expecting license at: /workspace/licenses/access.ilm | exists: False\n", "CPLEX OK — version: 22.1.2.0\n", "License file in use: /workspace/licenses/access.ilm\n" ] } ], "source": [ "# === Cell A: check CPLEX license inside the container and fix env vars ===\n", "import os, pathlib, cplex\n", "\n", "# 1) point to your license file INSIDE the container\n", "# adjust this path if your license lives elsewhere in the bind-mounted project\n", "lic_path = \"/workspace/licenses/access.ilm\" # <-- put your .ilm/.dat here\n", "print(\"Expecting license at:\", lic_path, \"| exists:\", pathlib.Path(lic_path).exists())\n", "\n", "# 2) export env vars for this kernel session\n", "os.environ[\"ILOG_LICENSE_FILE\"] = lic_path\n", "# if you installed CPLEX Studio, keep these too (they should already be in your Dockerfile)\n", "os.environ[\"CPLEX_STUDIO_DIR221\"] = os.environ.get(\"CPLEX_STUDIO_DIR221\", \"/opt/ibm/ILOG/CPLEX_Studio221\")\n", "os.environ[\"PATH\"] = os.environ[\"CPLEX_STUDIO_DIR221\"] + \"/cplex/bin/x86-64_linux:\" + os.environ[\"PATH\"]\n", "os.environ[\"LD_LIBRARY_PATH\"] = os.environ[\"CPLEX_STUDIO_DIR221\"] + \"/cplex/bin/x86-64_linux:\" + os.environ.get(\"LD_LIBRARY_PATH\",\"\")\n", "\n", "# 3) quick license sanity: create a tiny LP; CPLEX CE 1016 will fail here if license not found\n", "try:\n", " cp = cplex.Cplex()\n", " cp.set_results_stream(None); cp.set_log_stream(None); cp.set_warning_stream(None); cp.set_error_stream(None)\n", " # min x\n", " # s.t. x >= 0\n", " # trivial clip problem (well below CE limits)\n", " cp.variables.add(obj=[1.0], lb=[0.0], ub=[1e9], types=[cp.variables.type.continuous], names=[\"x\"])\n", " cp.objective.set_sense(cp.objective.sense.minimize)\n", " cp.solve()\n", " print(\"CPLEX OK — version:\", cp.get_version())\n", " print(\"License file in use:\", os.environ.get(\"ILOG_LICENSE_FILE\"))\n", " licensed_ok = True\n", "except Exception as e:\n", " print(\"CPLEX still not licensed inside the container:\", e)\n", " print(\"If the path above is wrong, move/copy your license to /workspace/licenses/access.ilm \"\n", " \"and re-run this cell. Otherwise set ILOG_LICENSE_FILE to the correct path.\")\n", " licensed_ok = False\n" ] }, { "cell_type": "code", "execution_count": 86, "id": "2f0a283d-f3bd-402d-a176-9ad498b74a1a", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Solver fallback armed. FORCE_GLPK = False\n" ] } ], "source": [ "# === Cell B: Robust solver fallback (force GLPK if needed) + quieter logs ===\n", "import logging, os\n", "FORCE_GLPK = not os.environ.get(\"ILOG_LICENSE_FILE\") # force GLPK unless license set\n", "\n", "# mute ETFL/pyTFA/cobra spam to avoid IOPub limit\n", "for name in (\"ME modelNone\",\"pytfa\",\"cobra\",\"optlang\"):\n", " try:\n", " logging.getLogger(name).setLevel(logging.ERROR)\n", " except Exception:\n", " pass\n", "\n", "def optimize_with_fallback(model):\n", " \"\"\"Use CPLEX when available; otherwise GLPK. Never raise 1016 to the notebook.\"\"\"\n", " if not FORCE_GLPK:\n", " try:\n", " model.solver = \"cplex\"\n", " return \"cplex\", model.optimize()\n", " except Exception:\n", " pass\n", " # fall back to GLPK\n", " try:\n", " model.solver = \"glpk_exact\"\n", " except Exception:\n", " model.solver = \"glpk\"\n", " return str(model.solver), model.optimize()\n", "\n", "print(\"Solver fallback armed. FORCE_GLPK =\", FORCE_GLPK)\n" ] }, { "cell_type": "code", "execution_count": 106, "id": "9eb363b8-f1a4-409a-8384-0afd0f9d1d15", "metadata": { "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "=== In-vitro L-DOPA production test ===\n", "Status: infeasible\n", "L-DOPA export flux: 0.000000 mmol/gDW/h\n", "Approx. total ATP demand: 7.90 mmol/gDW/h\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", "
envstatusL-DOPA_fluxATP_totalATPMPlasmid_ATP
0in-vitro L-DOPA mix (engineered TPL)infeasible0.07.9028.390.5
\n", "
" ], "text/plain": [ " env status L-DOPA_flux ATP_total \\\n", "0 in-vitro L-DOPA mix (engineered TPL) infeasible 0.0 7.902 \n", "\n", " ATPM Plasmid_ATP \n", "0 8.39 0.5 " ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# === Cell 12D: Final ETFL-safe engineered TPL + full in-vitro L-DOPA medium ===\n", "import logging, pandas as pd, time\n", "from cobra import Reaction, Metabolite\n", "from cobra.util.solver import set_objective\n", "\n", "# ---------------- solver/quiet setup ----------------\n", "for n in (\"pytfa\",\"cobra\",\"optlang\"):\n", " try: logging.getLogger(n).setLevel(logging.ERROR)\n", " except: pass\n", "\n", "def set_glpk(model):\n", " try: model.solver=\"glpk_exact\"\n", " except: model.solver=\"glpk\"\n", "\n", "def safe_opt(model,tmax=90):\n", " set_glpk(model)\n", " t0=time.time()\n", " sol=model.optimize()\n", " if time.time()-t0>tmax and not hasattr(sol,\"objective_value\"):\n", " val=0\n", " try: val=model.slim_optimize()\n", " except: pass\n", " class _S: pass\n", " s=_S(); s.status=\"timeout\"; s.objective_value=val; s.fluxes=getattr(sol,\"fluxes\",pd.Series(dtype=float))\n", " return s\n", " return sol\n", "\n", "# ---------------- helpers ----------------\n", "def has_rxn(rid): return rid in [r.id for r in etfl_model.reactions]\n", "def rxn(rid): return etfl_model.reactions.get_by_id(rid)\n", "def getM(mid,name=None,c=\"c\"):\n", " try: return etfl_model.metabolites.get_by_id(mid)\n", " except KeyError:\n", " m=Metabolite(mid,name or mid,compartment=c)\n", " etfl_model.add_metabolites([m]); return m\n", "\n", "# ---------------- realism drains ----------------\n", "def enforce_realism():\n", " atp,adp,pi,h2o,h=[getM(x) for x in (\"atp_c\",\"adp_c\",\"pi_c\",\"h2o_c\",\"h_c\")]\n", " if not has_rxn(\"ATPM\"):\n", " R=Reaction(\"ATPM\"); R.lower_bound=8.39;R.upper_bound=1000\n", " R.add_metabolites({atp:-1,h2o:-1,adp:1,pi:1,h:1}); etfl_model.add_reactions([R])\n", " else: rxn(\"ATPM\").lower_bound=8.39\n", " if not has_rxn(\"Plasmid_repl\"):\n", " R=Reaction(\"Plasmid_repl\");R.lower_bound=0.5;R.upper_bound=1000\n", " R.add_metabolites({atp:-1,h2o:-1,adp:1,pi:1,h:1}); etfl_model.add_reactions([R])\n", " else: rxn(\"Plasmid_repl\").lower_bound=0.5\n", " for rid in (\"TX_mazE\",\"TX_mazF\",\"TL_mazE\",\"TL_mazF\"):\n", " if has_rxn(rid): rxn(rid).lower_bound=0.0\n", "\n", "# ---------------- build engineered TPL (no deletions) ----------------\n", "# IDs from your model (confirmed earlier)\n", "catechol_id=\"catechol_c\"\n", "pyruvate_id=\"3mcat_c\" # used in your model instead of pyr_c\n", "ammonium_id=\"nh4_c\"\n", "ldopa_id=\"L_DOPA_c\"\n", "phenol_id=\"phenol_c\"\n", "\n", "cat=getM(catechol_id,\"catechol\",\"c\")\n", "pyr=getM(pyruvate_id,\"pyruvate\",\"c\")\n", "nh4=getM(ammonium_id,\"ammonium\",\"c\")\n", "ldo=getM(ldopa_id,\"L-DOPA\",\"c\")\n", "phe=getM(phenol_id,\"phenol\",\"c\")\n", "h2o=getM(\"h2o_c\",\"H2O\",\"c\")\n", "\n", "# deactivate any previous TPL flux (don't remove, safe for ETFL)\n", "if has_rxn(\"TPL\"):\n", " rxn(\"TPL\").lower_bound=0.0; rxn(\"TPL\").upper_bound=0.0\n", "\n", "# add engineered version with unique ID\n", "if not has_rxn(\"TPL_engineered\"):\n", " TPL=Reaction(\"TPL_engineered\")\n", " TPL.name=\"Engineered Tyrosine phenol-lyase (catechol+pyruvate+NH3→L-DOPA+phenol+H2O)\"\n", " TPL.lower_bound=0.0; TPL.upper_bound=1000.0\n", " TPL.add_metabolites({cat:-1.0,pyr:-1.0,nh4:-1.0,ldo:1.0,phe:1.0,h2o:1.0})\n", " etfl_model.add_reactions([TPL])\n", "\n", "# ---------------- add transport & exchange ----------------\n", "ldopa_e=getM(\"L_DOPA_e\",\"L-DOPA ext\",\"e\")\n", "if not has_rxn(\"LDOPA_tx\"):\n", " R=Reaction(\"LDOPA_tx\");R.lower_bound=0.0;R.upper_bound=1000\n", " R.add_metabolites({ldo:-1.0,ldopa_e:1.0}); etfl_model.add_reactions([R])\n", "if not has_rxn(\"EX_L_DOPA_e\"):\n", " R=Reaction(\"EX_L_DOPA_e\");R.lower_bound=0.0;R.upper_bound=1000\n", " R.add_metabolites({ldopa_e:-1.0}); etfl_model.add_reactions([R])\n", "\n", "# ---------------- in-vitro L-DOPA mix medium ----------------\n", "for R in etfl_model.reactions:\n", " if R.id.startswith(\"EX_\"): R.lower_bound=0.0\n", "ess=[(\"h2o_e\",-1000),(\"h_e\",-1000),(\"co2_e\",0),(\"pi_e\",-1000),(\"so4_e\",-1000),\n", " (\"nh4_e\",-1000),(\"mg2_e\",-1000),(\"ca2_e\",-1000),(\"k_e\",-1000),\n", " (\"na_e\",-1000),(\"cl_e\",-1000)]\n", "subs=[(\"catechol_e\",-10),(\"3mcat_e\",-10),(\"nh4_e\",-1000),(\"o2_e\",-1000),\n", " (\"pydx5p_e\",-0.5)]\n", "for ex,lb in ess+subs:\n", " if ex not in [r.id for r in etfl_model.metabolites]:\n", " m=Metabolite(ex,ex,\"e\");etfl_model.add_metabolites([m])\n", " rid=\"EX_\"+ex if not ex.startswith(\"EX_\") else ex\n", " if rid not in [r.id for r in etfl_model.reactions]:\n", " R=Reaction(rid);R.lower_bound=lb;R.upper_bound=1000\n", " met=etfl_model.metabolites.get_by_id(ex)\n", " R.add_metabolites({met:-1.0});etfl_model.add_reactions([R])\n", " else:\n", " rxn(rid).lower_bound=min(rxn(rid).lower_bound,lb)\n", "\n", "# ---------------- optimize for L-DOPA export ----------------\n", "enforce_realism()\n", "set_objective(etfl_model,{rxn(\"EX_L_DOPA_e\"):1.0},additive=False)\n", "set_glpk(etfl_model)\n", "sol=safe_opt(etfl_model)\n", "val=float(getattr(sol,\"objective_value\",0.0) or 0.0)\n", "\n", "# ---------------- report ----------------\n", "atp=getM(\"atp_c\")\n", "ATP_total=0.0\n", "if hasattr(sol,\"fluxes\"):\n", " for rid,v in sol.fluxes.items():\n", " if abs(v)<1e-12: continue\n", " try:R=rxn(rid)\n", " except KeyError:continue\n", " if atp in R.metabolites and R.metabolites[atp]<0:\n", " ATP_total+=-R.metabolites[atp]*v\n", "\n", "print(f\"\\n=== In-vitro L-DOPA production test ===\")\n", "print(f\"Status: {sol.status}\")\n", "print(f\"L-DOPA export flux: {val:.6f} mmol/gDW/h\")\n", "print(f\"Approx. total ATP demand: {ATP_total:.2f} mmol/gDW/h\")\n", "df=pd.DataFrame([{\n", " \"env\":\"in-vitro L-DOPA mix (engineered TPL)\",\n", " \"status\":sol.status,\n", " \"L-DOPA_flux\":val,\n", " \"ATP_total\":round(ATP_total,3),\n", " \"ATPM\":float(sol.fluxes.get(\"ATPM\",0.0)) if hasattr(sol,\"fluxes\") else 0.0,\n", " \"Plasmid_ATP\":float(sol.fluxes.get(\"Plasmid_repl\",0.0)) if hasattr(sol,\"fluxes\") and has_rxn(\"Plasmid_repl\") else 0.0\n", "}])\n", "display(df)\n" ] }, { "cell_type": "code", "execution_count": 107, "id": "bc978de1-bc39-440d-86ba-4ff10963348e", "metadata": {}, "outputs": [], "source": [ "# === Cell 15: Mechanistic Quorum Sensing + MazE/MazF ODE and FBA couplers ===\n", "import math\n", "\n", "# ---------- Parameter packs (literature ballparks, tune if you have data) ----------\n", "QS_PARAMS = dict(\n", " USE_MECH_QS = True,\n", " alpha_AHL = 1.0, # AHL synthesis rate ∝ biomass (arb. units per gDW·h)\n", " deg_AHL = 0.2, # AHL degradation (h^-1)\n", " alpha_LuxR = 0.5, # LuxR synthesis rate ∝ biomass (arb. per gDW·h)\n", " deg_LuxR = 0.1, # LuxR degradation (h^-1)\n", " bind_rate = 1.0, # LuxR•AHL association (1/(h·mM))\n", " unbind_rate = 0.1, # dissociation (h^-1)\n", " deg_complex = 0.1, # LuxR•AHL complex degradation (h^-1)\n", " hill_n = 2.0, # promoter Hill n\n", " K_complex = 1.0 # half-sat (mM in the same “units” you feed AHL_ext)\n", ")\n", "\n", "MAZEF_PARAMS = dict(\n", " USE_MECH_KS = True,\n", " Inducer_off_time = 10.0, # h (MazE inducer off after this; keep 10h for generality)\n", " prod_MazE = 1.0, deg_MazE = 0.5, # MazE: fast turnover (t1/2~1.4h)\n", " prod_MazF = 0.2, deg_MazF = 0.05, # MazF: stable (t1/2~14h)\n", " bind_Maz = 10.0, unbind_Maz = 0.1, # MazE–MazF reactions\n", " k_cleave = 0.1, deg_mRNA = 0.1, # mRNA cleavage & natural decay\n", " alpha_enforce = 0.8 # MazF enforcement: LB(cleavage)=α·ΣTX\n", ")\n", "\n", "# ---------- initialize QS & TA states ----------\n", "def qs_init_state():\n", " \"\"\"Return a dict holding mechanistic QS state for one cell/agent.\"\"\"\n", " return {\"AHL_i\":0.0, \"LuxR\":0.0, \"Complex\":0.0}\n", "\n", "def mazef_init_state():\n", " \"\"\"Return a dict holding mechanistic MazE/MazF state for one cell/agent.\"\"\"\n", " return {\"MazE\":1.0, \"MazF\":0.05, \"MazEF\":0.0, \"mRNA_g\":1.0, \"mRNA_tpl\":0.2}\n", "\n", "# ---------- single-step QS ODE (Euler) ----------\n", "def qs_step(state, X_gDW, AHL_ext_mM, dt_h, params=QS_PARAMS, flow_rate=0.0, USE_FLOW_ENV=False):\n", " \"\"\"\n", " Update LuxR/AHL_i/Complex; return (new_state, activation_fraction).\n", " X_gDW: local biomass (gDW) used to scale synthesis rates.\n", " AHL_ext_mM: extracellular AHL concentration at voxel (mM).\n", " \"\"\"\n", " if not params[\"USE_MECH_QS\"]:\n", " return state, 0.0\n", "\n", " AHL_i = state[\"AHL_i\"]; LuxR = state[\"LuxR\"]; C = state[\"Complex\"]\n", " # production/decay\n", " dAHL_i = params[\"alpha_AHL\"]*max(0.0,X_gDW) - params[\"deg_AHL\"]*AHL_i\n", " dLuxR = params[\"alpha_LuxR\"]*max(0.0,X_gDW) - params[\"deg_LuxR\"]*LuxR\n", " # binding/unbinding with extracellular AHL\n", " bind = params[\"bind_rate\"]*LuxR*AHL_ext_mM\n", " unbind = params[\"unbind_rate\"]*C\n", " dLuxR -= bind; dAHL_i -= bind; dC = bind\n", " dLuxR += unbind; dAHL_i += unbind; dC -= unbind\n", " dC -= params[\"deg_complex\"]*C\n", "\n", " if USE_FLOW_ENV:\n", " # Only extracellular AHL is diluted by flow; we keep the intracellular proxy undiluted for simplicity.\n", " pass\n", "\n", " # integrate (Euler)\n", " AHL_i = max(0.0, AHL_i + dAHL_i*dt_h)\n", " LuxR = max(0.0, LuxR + dLuxR*dt_h)\n", " C = max(0.0, C + dC*dt_h)\n", "\n", " state.update({\"AHL_i\":AHL_i, \"LuxR\":LuxR, \"Complex\":C})\n", "\n", " # Hill activation: 0..1\n", " n = params[\"hill_n\"]; K = params[\"K_complex\"]\n", " act = (C**n)/(K**n + C**n) if C>0 else 0.0\n", " return state, float(act)\n", "\n", "# ---------- single-step MazE/MazF ODE (Euler) ----------\n", "def mazef_step(state, t_h, dt_h, params=MAZEF_PARAMS, flow_rate=0.0, USE_FLOW_ENV=False):\n", " \"\"\"\n", " Update MazE/MazF/MazEF + mRNA pools; return (new_state, mRNA_g_frac, enforce_flag).\n", " enforce_flag=True when MazF becomes significant and should enforce cleavage LB in FBA.\n", " \"\"\"\n", " if not params[\"USE_MECH_KS\"]:\n", " return state, 1.0, False\n", "\n", " MazE=state[\"MazE\"]; MazF=state[\"MazF\"]; MazEF=state[\"MazEF\"]\n", " mg=state[\"mRNA_g\"]; mt=state[\"mRNA_tpl\"]\n", "\n", " Inducer = 1.0 if t_h < params[\"Inducer_off_time\"] else 0.0\n", " dE = params[\"prod_MazE\"]*Inducer - params[\"deg_MazE\"]*MazE\n", " dF = params[\"prod_MazF\"] - params[\"deg_MazF\"]*MazF\n", " bindEF = params[\"bind_Maz\"]*MazE*MazF\n", " unbindEF = params[\"unbind_Maz\"]*MazEF\n", " dE -= bindEF; dF -= bindEF; dEF = bindEF\n", " dE += unbindEF; dF += unbindEF; dEF -= unbindEF\n", "\n", " # integrate\n", " MazE = max(0.0, MazE + dE*dt_h)\n", " MazF = max(0.0, MazF + dF*dt_h)\n", " MazEF = max(0.0, MazEF + dEF*dt_h)\n", "\n", " # mRNA pools (growth-essential and tpl-related)\n", " mg = max(0.0, mg + dt_h*(1.0 - params[\"deg_mRNA\"]*mg - params[\"k_cleave\"]*MazF*mg))\n", " mt = max(0.0, mt + dt_h*(0.5 - params[\"deg_mRNA\"]*mt - params[\"k_cleave\"]*MazF*mt))\n", "\n", " state.update({\"MazE\":MazE, \"MazF\":MazF, \"MazEF\":MazEF, \"mRNA_g\":mg, \"mRNA_tpl\":mt})\n", "\n", " # if MazF is high enough or mRNA_g collapses, tell caller to enforce FBA cleavage LB\n", " enforce_flag = (MazF > 0.5) or (mg < 0.2)\n", " return state, float(mg), enforce_flag\n", "\n", "# ---------- Couplers into FBA ----------\n", "def set_tpl_gate(act_fraction):\n", " \"\"\"Scale TX_tpl UB by an activation fraction 0..1.\"\"\"\n", " try:\n", " r = etfl_model.reactions.get_by_id(\"TX_tpl\")\n", " r.upper_bound = 1000.0*float(max(0.0, min(1.0, act_fraction)))\n", " except Exception:\n", " pass\n", "\n", "def enforce_mazf_cleavage(alpha=0.8):\n", " \"\"\"Two-stage: OFF → measure ΣTX → ON with LB=α·ΣTX.\"\"\"\n", " try:\n", " r = etfl_model.reactions.get_by_id(\"MAZF_cleavage\")\n", " except Exception:\n", " return\n", " # Stage 1: OFF → measure ΣTX\n", " r.upper_bound = 0.0; r.lower_bound = 0.0\n", " set_glpk(etfl_model); pre = etfl_model.optimize()\n", " tx_sum = 0.0\n", " if hasattr(pre, \"fluxes\"):\n", " idx = [rid for rid in pre.fluxes.index if rid.startswith(\"TX_\")]\n", " if idx: tx_sum = float(pre.fluxes[idx].sum())\n", " # Stage 2: ON with LB\n", " r.upper_bound = 1000.0; r.lower_bound = max(0.0, float(alpha)*tx_sum)\n", "\n", "# ---------- convenience that you can call each step ----------\n", "def mech_regulation_step(qs_state, ta_state, X_gDW, AHL_ext_mM, t_h, dt_h,\n", " qs_params=QS_PARAMS, ta_params=MAZEF_PARAMS,\n", " use_flow=False, flow_rate=0.0):\n", " \"\"\"\n", " Update mechanistic modules and push constraints into the current FBA model:\n", " - QS → sets TX_tpl UB via Hill activation\n", " - MazF → optionally enforces cleavage LB = α·ΣTX\n", " Returns (new_qs_state, new_ta_state, activation_fraction, enforced_flag).\n", " \"\"\"\n", " qs_state, act = qs_step(qs_state, X_gDW, AHL_ext_mM, dt_h, qs_params, flow_rate, use_flow)\n", " set_tpl_gate(act)\n", "\n", " ta_state, mg_frac, enforce_flag = mazef_step(ta_state, t_h, dt_h, ta_params, flow_rate, use_flow)\n", " if enforce_flag:\n", " enforce_mazf_cleavage(alpha=ta_params[\"alpha_enforce\"])\n", " else:\n", " # keep MazF OFF if not enforced\n", " try:\n", " r = etfl_model.reactions.get_by_id(\"MAZF_cleavage\")\n", " r.upper_bound = 0.0; r.lower_bound = 0.0\n", " except Exception:\n", " pass\n", " return qs_state, ta_state, float(act), bool(enforce_flag)\n" ] }, { "cell_type": "code", "execution_count": 108, "id": "96ffe26f-9540-42bb-befd-7ed305b2c053", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Temperature unchanged (T=37.0°C).\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", "
t_minmuAHL_extglc_mMo2_mMldopa_ex
00.00.00.09.976482999.858890.0
10.50.00.09.952963999.717780.0
21.00.00.09.929445999.576670.0
31.50.00.09.905927999.435560.0
42.00.00.09.882408999.294450.0
\n", "
" ], "text/plain": [ " t_min mu AHL_ext glc_mM o2_mM ldopa_ex\n", "0 0.0 0.0 0.0 9.976482 999.85889 0.0\n", "1 0.5 0.0 0.0 9.952963 999.71778 0.0\n", "2 1.0 0.0 0.0 9.929445 999.57667 0.0\n", "3 1.5 0.0 0.0 9.905927 999.43556 0.0\n", "4 2.0 0.0 0.0 9.882408 999.29445 0.0" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "Saved: /workspace/results/single_cell_15min_mech.csv\n" ] }, { "data": { "image/png": "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f37HxVWWL1+eysr/Pjl50EEH5aabbsp5552Xc845J3vssUfuuOOO7LPPPuU6BAAAgB5VUSqVSuUeordraWlJTU1NmpubfT4PAADoEV3tjl7zmTwAAADen8gDAAAoEJEHAABQICIPAACgQEQeAABAgYg8AACAAhF5AAAABSLyAAAACkTkAQAAFIjIAwAAKBCRBwAAUCAiDwAAoEBEHgAAQIGIPAAAgAIReQAAAAUi8gAAAApE5AEAABSIyAMAACgQkQcAAFAgIg8AAKBARB4AAECBiDwAAIACEXkAAAAFIvIAAAAKROQBAAAUiMgDAAAoEJEHAABQICIPAACgQEQeAABAgYg8AACAAhF5AAAABSLyAAAACkTkAQAAFIjIAwAAKBCRBwAAUCAiDwAAoEBEHgAAQIGIPAAAgAIReQAAAAUi8gAAAApE5AEAABSIyAMAACgQkQcAAFAgIg8AAKBAel3kXXXVVRk9enQGDBiQyZMn57HHHtvk+ltvvTVjxozJgAEDMm7cuNx1110d97W2tuass87KuHHjst1226Wuri5HH310VqxY0dOHAQAA0CN6VeTdcsstmT17di688MIsWbIk++23X+rr67Ny5coNrn/44Yczc+bMnHDCCXniiScyffr0TJ8+PU899VSSZO3atVmyZEnOP//8LFmyJLfddluWLl2aP//zP9+ShwUAANBtKkqlUqncQ3TV5MmTc8ABB+TKK69MkrS3t2fkyJE55ZRTcvbZZ79n/ZFHHpk1a9bkzjvv7Nh24IEHZvz48Zk3b94Gn2PRokWZNGlSli1bllGjRnVprpaWltTU1KS5uTnV1dUf4MgAAAA2ravd0WvO5L3zzjtZvHhxpk2b1rGtsrIy06ZNS0NDwwb3aWho6LQ+Serr6ze6Pkmam5tTUVGRwYMHd8vcAAAAW1Kfcg/QVa+//nra2toyYsSITttHjBiR5557boP7NDY2bnB9Y2PjBte//fbbOeusszJz5sxNlvG6deuybt26jp9bWlq6ehgAAAA9qtecyetpra2tOeKII1IqlXLNNddscu3cuXNTU1PTcRs5cuQWmhIAAGDTek3k7bjjjqmqqkpTU1On7U1NTamtrd3gPrW1tV1avz7wli1blgULFrzv5+rmzJmT5ubmjtsrr7zyAY4IAACg+/WayOvXr18mTJiQhQsXdmxrb2/PwoUL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6DG9JvJmzZqVp59+OgsWLMidd96ZBx54ICeeeOIm9/nyl7+cH//4x7n11ltz//33Z8WKFfnsZz/bcf/ixYszfPjwfP/738/TTz+dc889N3PmzMmVV17Z04cDAADQIypKpVKp3EO8n2effTZ77bVXFi1alIkTJyZJ5s+fn09/+tP59a9/nbq6uvfs09zcnGHDhuWmm27K4YcfniR57rnnMnbs2DQ0NOTAAw/c4HOddNJJefbZZ3Pvvfd2eb6WlpbU1NSkubk51dXVH+AIAQAANq2r3dErzuQ1NDRk8ODBHYGXJNOmTUtlZWUeffTRDe6zePHitLa2Ztq0aR3bxowZk1GjRqWhoWGjz9Xc3JwhQ4Z03/AAAABbUJ9yD9AVjY2NGT58eKdtffr0yZAhQ9LY2LjRffr165fBgwd32j5ixIiN7vPwww/nlltuyU9+8pNNzrNu3bqsW7eu4+eWlpYuHAUAAEDPK+uZvLPPPjsVFRWbvD333HNbZJannnoqf/EXf5ELL7wwf/Znf7bJtXPnzk1NTU3HbeTIkVtkRgAAgPdT1jN5Z5xxRo499thNrvnIRz6S2trarFy5stP2d999N6tWrUptbe0G96utrc0777yT1atXdzqb19TU9J59nnnmmUydOjUnnnhizjvvvPede86cOZk9e3bHzy0tLUIPAADYKpQ18oYNG5Zhw4a977opU6Zk9erVWbx4cSZMmJAkuffee9Pe3p7JkydvcJ8JEyakb9++WbhwYWbMmJEkWbp0aZYvX54pU6Z0rHv66afzqU99Ksccc0y++c1vdmnu/v37p3///l1aCwAAsCX1iqtrJsmhhx6apqamzJs3L62trTnuuOMyceLE3HTTTUmSV199NVOnTs0NN9yQSZMmJUm+9KUv5a677sr111+f6urqnHLKKUl+99m75Hdv0fzUpz6V+vr6fPvb3+54rqqqqi7F53qurgkAAPS0rnZHr7jwSpLceOONOfnkkzN16tRUVlZmxowZueKKKzrub21tzdKlS7N27dqObd/5znc61q5bty719fW5+uqrO+7/4Q9/mNdeey3f//738/3vf79j+6677pqXX355ixwXAABAd+o1Z/K2Zs7kAQAAPa1Q35MHAABA14g8AACAAhF5AAAABSLyAAAACkTkAQAAFIjIAwAAKBCRBwAAUCAiDwAAoEBEHgAAQIGIPAAAgAIReQAAAAUi8gAAAApE5AEAABSIyAMAACgQkQcAAFAgIg8AAKBARB4AAECBiDwAAIACEXkAAAAFIvIAAAAKROQBAAAUiMgDAAAoEJEHAABQICIPAACgQEQeAABAgYg8AACAAhF5AAAABSLyAAAACkTkAQAAFIjIAwAAKBCRBwAAUCAiDwAAoEBEHgAAQIGIPAAAgAIReQAAAAUi8gAAAApE5AEAABSIyAMAACgQkQcAAFAgIg8AAKBARB4AAECBiDwAAIACEXkAAAAFIvIAAAAKROQBAAAUSK+JvFWrVmXWrFmprq7O4MGDc8IJJ+TNN9/c5D5vv/12TjrppAwdOjTbb799ZsyYkaampg2u/a//+q/ssssuqaioyOrVq3vgCAAAAHper4m8WbNm5emnn86CBQty55135oEHHsiJJ564yX2+/OUv58c//nFuvfXW3H///VmxYkU++9nPbnDtCSeckH333bcnRgcAANhiKkqlUqncQ7yfZ599NnvttVcWLVqUiRMnJknmz5+fT3/60/n1r3+durq69+zT3NycYcOG5aabbsrhhx+eJHnuuecyduzYNDQ05MADD+xYe8011+SWW27JBRdckKlTp+a3v/1tBg8e3OX5WlpaUlNTk+bm5lRXV3+4gwUAANiArnZHrziT19DQkMGDB3cEXpJMmzYtlZWVefTRRze4z+LFi9Pa2ppp06Z1bBszZkxGjRqVhoaGjm3PPPNMLrrootxwww2prOzar2PdunVpaWnpdAMAANga9IrIa2xszPDhwztt69OnT4YMGZLGxsaN7tOvX7/3nJEbMWJExz7r1q3LzJkz8+1vfzujRo3q8jxz585NTU1Nx23kyJGbd0AAAAA9pKyRd/bZZ6eiomKTt+eee67Hnn/OnDkZO3ZsPv/5z2/2fs3NzR23V155pYcmBAAA2Dx9yvnkZ5xxRo499thNrvnIRz6S2trarFy5stP2d999N6tWrUptbe0G96utrc0777yT1atXdzqb19TU1LHPvffem1/84hf54Q9/mCRZ//HEHXfcMeeee26+/vWvb/Cx+/fvn/79+3flEAEAALaoskbesGHDMmzYsPddN2XKlKxevTqLFy/OhAkTkvwu0Nrb2zN58uQN7jNhwoT07ds3CxcuzIwZM5IkS5cuzfLlyzNlypQkyb/927/lrbfe6thn0aJF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ttvyta99LRMmTPiwv4qNciYPAAAom7333jvbb799tt9++xx66KHvu379GcT/+X1ym3NW8c4778z222+fAQMG5NBDD82RRx6Zr33ta0mS6667LkceeWT69PndubCZM2fmP//zP/Piiy9u9PF+9rOf5frrr+84hu233z719fVpb2/PSy+9lCT5gz/4g3z3u9/NNddck9133z1nn312l+f9IJzJAwCAXqpq4MAcUaYrQFYNHNgtj3PXXXeltbU1ye/eOvl+nn322STJ6NGjM3To0AwePLhj24bWVlRU5KMf/WjHtk9+8pO55pprOq7CuT7oVq1aldtvvz2tra255pprOta3tbXluuuuyze/+c0NPsebb76Zv/mbv8mpp576nvtGjRrV8d8PPPBAqqqq8pvf/CZr1qzJDjvs8L7H+kGJPAAA6KUqKirK8pbJ7rTrrrt2ee1bb72Va6+9Nn/8x3+cYcOGJUmOOOKI3Hjjjbnooos6fS7vrbfeytVXX536+voMGTKkY/t2223XKfrWu/HGG7PLLrvkjjvu6LT9P/7jP3LppZfmoosuSlVV1Xv2+/jHP55nnnlmg4+53sMPP5yLL744P/7xj3PWWWfl5JNPzr/8y790+bg3l8gDAAB6XHNzc5588slO24YOHZqRI0dudJ+VK1fm7bffzhtvvJHFixfnkksuyeuvv57bbrutY823vvWtLFy4MH/6p3+aSy65JPvss09eeumlnHfeeWltbc1VV13Vpfm++93v5vDDD88+++zTafvIkSMzZ86czJ8/P4cddth79jvrrLNy4IEH5uSTT87/9//9f9luu+3yzDPPZMGCBbnyyivzxhtv5Kijjsqpp56aQw89NLvssksOOOCAfOYzn8nhhx/epdk2l8/kAQAAPe6nP/1p9t9//063r3/965vcZ88990xdXV0mTJiQv//7v8+0adPy1FNPZa+99upYM3To0DzyyCP55Cc/mb/5m7/J7rvvniOOOCK77757Fi1alI985CPvO9vixYvzs5/9LDNmzHjPfTU1NZk6dWq++93vbnDffffdN/fff39++ctf5o/+6I+y//7754ILLkhdXV2S5LTTTst2222Xb33rW0mScePG5Vvf+lb+5m/+Jq+++ur7zvZBVJTKce3TgmlpaUlNTU2am5tTXV1d7nEAACigt99+Oy+99FJ22223DBgw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AgAA6H69JvL69euXCRMmZOHChR3b2tvbs3DhwkyZMmWD+0yZMqXT+iRZsGBBp/XrA+/555/PPffck6FDh77vLP379091dXWnGwAAwNag13wmL0lmz56dY445JhMnTsykSZNy2WWXZc2aNTnuuOOSJEcffXR23nnnzJ07N0ly2mmn5eCDD86ll16aww47LDfffHMef/zxXHvttUl+F3iHH354lixZkjvvvDNtbW0dn9cbMmRI+vXrV54DBQAA+IB6VeQdeeSRee2113LBBReksbEx48ePz/z58zsurrJ8+fJUVv73ycmDDjooN910U84777ycc8452WOPPXLHHXdkn332SZK8+uqr+dGPfpQkGT9+fKfnuu+++/Inf/InW+S4AAAAukuv+p68rZXvyQMAAHpa4b4nDwAAgPcn8gAAAApE5AEAABSIyAMAACgQkQcAAFAgIg8AAKBARB4AAECBiDwAAIACEXkAAAAFIvIAAAAKROQBAAAUiMgDAAAoEJEHAABQICIPAACgQEQeAABAgYg8AACAAhF5AAAABSLyAAAACkTkAQAAFIjIAwAAKBCRBwAAUCAiDwAAoEBEHgAAQIGIPAAAgAIReQAAAAUi8gAAAApE5AEAABSIyAMAACgQkQcAAFAgIg8AAKBARB4AAECBiDwAAIACEXkAAAAFIvIAAAAKROQBAAAUiMgDAAAoEJEHAABQICIPAACgQEQeAABAgYg8AACAAhF5AAAABSLyAAAACkTkAQAAFIjIAwAAKBCRBwAAUCC9LvKuuuqqjB49OgMGDMjkyZPz2GOPbXL9rbfemjFjxmTAgAEZN25c7rrrrk73l0qlXHDBBdlpp50ycODATJs2Lc8//3xPHgIAAECP6VWRd8stt2T27Nm58MILs2TJkuy3336pr6/PypUrN7j+4YcfzsyZM3PCCSfkiSeeyPTp0zN9+vQ89dRTHWsuueSSXHHFFZk3b14effTRbLfddqmvr8/bb7+9pQ4LAACg21SUSqVSuYfoqsmTJ+eAAw7IlVdemSRpb2/PyJEjc8opp+Tss89+z/ojjzwya9asyZ133tmx7cADD8z48eMzb968lEql1NXV5YwzzshXvvKVJElzc3NGjBiR66+/Pp/73Oe6NFdLS0tqamrS3Nyc6urqbjjSD65UKqXtrbfKOgMAABRJ1cCBqaioKPcYXe6OPltwpg/lnXfeyeLFizNnzpyObZWVlZk2bVoaGho2uE9DQ0Nmz57daVt9fX3uuOOOJMlLL72UxsbGTJs2reP+mpqaTJ48OQ0NDRuNvHXr1mXdunUdP7e0tHzQw+p2bW+9lX894IByjwEAAIVxxKJF6TNoULnH6LJe83bN119/PW1tbRkxYkSn7SNGjEhjY+MG92lsbNzk+vX/uzmPmSRz585NTU1Nx23kyJGbfTwAAAA9odecyduazJkzp9MZwpaWlq0m9KoGDswRixaVewwAACiMqoEDyz3CZuk1kbfjjjumqqoqTU1NnbY3NTWltrZ2g/vU1tZucv36/21qaspOO+3Uac348eM3Okv//v3Tv3//D3IYPa6ioqJXnUoGAAC6V695u2a/fv0yYcKELFy4sGNbe3t7Fi5cmClTpmxwnylTpnRanyQLFizoWL/bbrultra205qWlpY8+uijG31MAACArVmvOZOXJLNnz84xxxyTiRMnZtKkSbnsssuyZs2aHHfccUmSo48+OjvvvHPmzp2bJDnttNNy8MEH59JLL81hhx2Wm2++OY8//niuvfbaJL8763X66afnG9/4RvbYY4/stttuOf/881NXV5fp06eX6zABAAA+sF4VeUceeWRee+21XHDBBWlsbMz48eMzf/78jgunLF++PJWV/31y8qCDDspNN92U8847L+ecc0722GOP3HHHHdlnn3061nz1q1/NmjVrcuKJJ2b16tX5wz/8w8yfPz8DBgzY4scHAADwYfWq78nbWm1N35MHAAAUU1e7o9d8Jg8AAID3J/IAAAAKROQBAAAUiMgDAAAoEJEHAABQICIPAACgQEQeAABAgYg8AACAAhF5AAAABSLyAAAACkTkAQAAFIjIAwAAKBCRBwAAUCAiDwAAoEBEHgAAQIGIPAAAgAIReQAAAAUi8gAAAApE5AEAABSIyAMAACgQkQcAAFAgIg8AAKBARB4AAECBiDwAAIACEXkAAAAFIvIAAAAKROQBAAAUiMgDAAAoEJEHAABQICIPAACgQEQeAABAgYg8AACAAhF5AAAABSLyAAAACkTkAQAAFIjIAwAAKBCRBwAAUCAiDwAAoEBEHgAAQIGIPAAAgAIReQAAAAUi8gAAAApE5AEAABSIyAMAACiQXhN5q1atyqxZs1JdXZ3BgwfnhBNOyJtvvrnJfd5+++2cdNJJGTp0aLbffvvMmDEjTU1NHff/7Gc/y8yZMzNy5MgMHDgwY8eOzeWXX97ThwIAANBjek3kzZo1K08//XQWLFiQO++8Mw888EBOPPHETe7z5S9/OT/+8Y9z66235v7778+KFSvy2c9+tuP+xYsXZ/jw4fn+97+fp59+Oueee27mzJmTK6+8sqcPBwAAoEdUlEqlUrmHeD/PPvts9tprryxatCgTJ05MksyfPz+f/vSn8+tf/zp1dXXv2ae5uTnDhg3LTTfdlMMPPzxJ8txzz2Xs2LFpaGjIgQceuMHnOumkk/Lss8/m3nvv7fJ8LS0tqampSXNzc6qrqz/AEQIAAGxaV7ujV5zJa2hoyODBgzsCL0mmTZuWysrKPProoxvcZ/HixWltbc20adM6to0ZMyajRo1KQ0PDRp+rubk5Q4YM2eQ869atS0tLS6cbAADA1qBXRF5jY2OGDx/eaVufPn0yZMiQNDY2bnSffv36ZfDgwZ22jxgxYqP7PPzww7nlllve922gc+fOTU1NTcdt5MiRXT8YAACAHlTWyDv77LNTUVGxydtzzz23RWZ56qmn8hd/8Re58MIL82d/9mebXDtnzpw0Nzd33F555ZUtMiMAAMD76VPOJz/jjDNy7LHHbnLNRz7ykdTW1mblypWdtr/77rtZtWpVamtrN7hfbW1t3nnnnaxevbrT2bympqb37PPMM89k6tSpOfHEE3Peeee979z9+/dP//7933cdAADAllbWyBs2bFiGDRv2vuumTJmS1atXZ/HixZkwYUKS5N577017e3smT568wX0mTJiQvn37ZuHChZkxY0aSZOnSpVm+fHmmTJnSse7pp5/Opz71qRxzzDH55je/2Q1HBQAAUD694uqaSXLooYemqakp8+bNS2tra4477rhMnDgxN910U5Lk1VdfzdSpU3PDDTdk0qRJSZIvfelLueuuu3L99denuro6p5xySpLfffYu+d1bND/1qU+lvr4+3/72tzueq6qqqkvxuZ6rawIAAD2tq91R1jN5m+PGG2/MySefnKlTp6aysjIzZszIFVdc0XF/a2trli5dmrVr13Zs+853vtOxdt26damvr8/VV1/dcf8Pf/jDvPbaa/n+97+f73//+x3bd91117z88stb5LgAAAC6U685k7c1cyYPAADoaYX6njwAAAC6RuQBAAAUiMgDAAAo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bly222671NXV5eijj86KFSvKN3ABvd+/g//pi1/8YioqKnLZZZdtsfm2RSKvQG655ZbMnj07F154YZYsWZL99tsv9fX1WblyZblH2ybcf//9Oemkk/LII49kwYIFaW1tzZ/92Z9lzZo15R5tm7Ro0aL80z/9U/bdd99yj7JN+e1vf5tPfOIT6du3b/793/89zzzzTC699NL8wR/8QblH22ZcfPHFueaaa3LllVfm2WefzcUXX5xLLrkk//iP/1ju0QppzZo12W+//XLVVVdt8P5LLrkkV1xxRebNm5dHH3002223Xerr6/P2229v4UmLa1Ovwdq1a7NkyZKcf/75WbJkSW677bYsXbo0f/7nf16GSYvr/f4drHf77bfnkUceSV1d3RaabBtWojAmTZpUOumkkzp+bmtrK9XV1ZXmzp1bxqm2XStXriwlKd1///3lHmWb88Ybb5T22GOP0oIFC0oHH3xw6bTTTiv3SNuMs846q/SHf/iH5R5jm3bYYYeVjj/++E7bPvvZz5ZmzZpVpom2HUlKt99+e8fP7e3tpdra2tK3v/3tjm2rV68u9e/fv/SDH/ygDBMW3++/Bhvy2GOPlZKUli1btmWG2sZs7DX49a9/Xdp5551LTz31VGnXXXctfec739nis21LnMkriHfeeSeLFy/OtGnTOrZVVlZm2rRpaWhoKONk267m5uYkyZAhQ8o8ybbnpJNOymGHHdbp3wNbxo9+9KNMnDgxf/VXf5Xhw4dn//33z//5P/+n3GNtUw466KAsXLgwv/zlL5MkP/vZz/LQQw/l0EMPLfNk256XXnopjY2Nnf6/qKamJpMnT/a3uYyam5tTUVGRwYMHl3uUbUZ7e3uOOuqonHnmmdl7773LPc42oU+5B6B7vP7662lra8uIESM6bR8xYkSee+65Mk217Wpvb8/pp5+eT3ziE9lnn33KPc425eabb86SJUuyaNGico+yTfrVr36Va665JrNnz84555yTRYsW5dRTT02/fv1yzDHHlHu8bcLZZ5+dlpaWjBkzJlVVVWlra8s3v/nNzJo1q9yjbXMaGxuTZIN/m9ffx5b19ttv56yzzsrMmTNTXV1d7nG2GRdffHH69OmTU089tdyjbDNEHvSAk046KU899VQeeuihco+yTXnllVdy2mmnZcGCBRkwYEC5x9kmtbe3Z+LEifnWt76VJNl///3z1FNPZd68eSJvC/nXf/3X3Hjjjbnpppuy995758knn8zpp5+euro6rwHbtNbW1hxxxBEplUq55ppryj3ONmPx4sW5/PLLs2TJklRUVJR7nG2Gt2sWxI477piqqqo0NTV12t7U1JTa2toyTbVtOvnkk3PnnXfmvvvuyy677FLucbYpixcvzsqVK/Pxj388ffr0SZ8+fXL//ffniiuuSJ8+fdLW1lbuEQtvp512yl577dVp29ixY7N8+fIyTbTtOfPMM3P22Wfnc5/7XMaNG5ejjjoqX/7ylzN37txyj7bNWf/319/m8lsfeMuWLcuCBQucxduCHnzwwaxcuTKjRo3q+Nu8bNmynHHGGRk9enS5xysskVcQ/fr1y4QJE7Jw4cKObe3t7Vm4cGGmTJlSxsm2HaVSKSeffHJuv/323Hvvvdltt93KPdI2Z+rUqfnFL36RJ598suM2ceLEzJo1K08++WSqqqrKPWLhfeITn3jPV4f88pe/zK677lqmibY9a9euTWVl5z/vVVVVaW9vL9NE267ddtsttbW1nf42t7S05NFHH/W3eQtaH3jPP/987rnnngwdOrTcI21TjjrqqPz85z/v9Le5rq4uZ555Zu6+++5yj1dY3q5ZILNnz84xxxyTiRMnZtKkSbnsssuyZs2aHHfcceUebZtw0kkn5aabbsr/+3//LzvssEPH5y1qamoycODAMk+3bdhhhx3e8xnI7bbbLkOHDvXZyC3ky1/+cg466KB861vfyhFHHJHHHnss1157ba699tpyj7bN+MxnPpNvfvObGTVqVPbee+888cQT+Yd/+Iccf/zx5R6tkN5888288MILHT+/9NJLefLJJzNkyJCMGjUqp59+er7xjW9kjz32yG677Zbzzz8/dXV1mT59evmGLphNvQY77bRTDj/88CxZsiR33nln2traOv4+DxkyJP369SvX2IXyfv8Ofj+s+/btm9ra2uy5555betRtR7kv70n3+sd//MfSqFGjSv369StNmjSp9Mgjj5R7pG1Gkg3evve975V7tG2ar1DY8n784x+X9tlnn1L//v1LY8aMKV177bXlHmmb0tLSUjrttNNKo0aNKg0YMKD0kY98pHTuueeW1q1bV+7RCum+++7b4P/3H3PMMaVS6Xdfo3D++eeXRowYUerfv39p6tSppaVLl5Z36ILZ1Gvw0ksvbfTv83333Vfu0Qvj/f4d/D5fodDzKkqlUmkL9SQAAAA9zGfyAAAACkTkAQAAFIjIAwAAKBCRBwAAUCAiDwAAoEBEHgAAQIGIPAAAgAIReQAAAAUi8gAAAApE5AGwTfvpT3+aioqKrF69uizPv3DhwowdOzZtbW0f6nEqKipyxx13dHn9/PnzM378+LS3t3+o5wVg6yPyANhm/Mmf/ElOP/30TtsOOuig/OY3v0lNTU1ZZvrqV7+a8847L1VVVR/qcX7zm9/k0EMP7fL6Qw45JH379s2NN974oZ4XgK2PyANgm9avX7/U1tamoqJiiz/3Qw89lBdffDEzZsz40I9VW1ub/v37b9Y+xx57bK644ooP/dwAbF1EHgDbhGOPPTb3339/Lr/88lRUVKSioiIvv/zye96uef3112fw4MG58847s+eee2bQoEE5/PDDs3bt2vzLv/xLRo8enT/4gz/Iqaee2uktluvWrctXvvKV7Lzzztluu+0yefLk/PSnP93kTDfffHP+9E//NAMGDOjY9rWvfS3jx4/Pddddl1GjRmX77bfP3/7t36atrS2XXHJJamtrM3z48Hzzm9/s9Fj/8+2aL7/8cioqKnLbbbflk5/8ZAYNGpT99tsvDQ0Nnfb5zGc+k8cffzwvvvjiB//FArDV6VPuAQBgS7j88svzy1/+Mvvss08uuuiiJMmwYcPy8ssvv2ft2rVrc8UVV+Tmm2/OG2+8kc9+9rP5y7/8ywwePDh33XVXfvWrX2XGjBn5xCc+kSOPPDJJcvLJJ+eZZ57JzTffnLq6utx+++055JBD8otf/CJ77LHHBmd68MEH89d//dfv2f7iiy/m3//93zN//vy8+OKLOfzww/OrX/0qH/vYx3L//ffn4YcfzvHHH59p06Zl8uTJGz3mc889N//7f//v7LHHHjn33HMzc+bMvPDCC+nT53d//keNGpURI0bkwQcfzO677765v1IAtlIiD4BtQk1NTfr165dBgwaltrZ2k2tbW1tzzTXXdITP4Ycfnv/7f/9vmpqasv3222evvfbKJz/5ydx333058sgjs3z58nzve9/L8uXLU1dXlyT5yle+kvnz5+d73/tevvWtb23weZYtW9ax/n9qb2/Pddddlx122KHjuZYuXZq77rorlZWV2XPPPXPxxRfnvvvu22TkfeUrX8lhhx2WJPn617+evffeOy+88ELGjBnTsaauri7Lli3b9C8PgF5F5AHA7xk0aFCnM1sjRozI6NGjs/3223fatnLlyiTJL37xi7S1teVjH/tYp8dZt25dhg4dutHneeuttzq9VXO90aNHZ4cdduj0XFVVVamsrOy0bf3zb8y+++7b8d877bRTkmTlypWdIm/gwIFZu3btJh8HgN5F5AHA7+nbt2+nnysqKja4bf3XD7z55pupqqrK4sWL33OVzP8Zhr9vxx13zG9/+9sP/fxdOY71F5b5/X1WrVqVYcOGbfJxAOhdRB4A24x+/fp96O+j25D9998/bW1tWblyZf7oj/5os/Z75plnun2ernr77bfz4osvZv/99y/bDAB0P1fXBGCbMXr06Dz66KN5+eWX8/rrr3fbF4F/7GMfy6xZs3L00Ufntttuy0svvZTHHnssc+fOzU9+8pON7ldfX5+HHnqoW2b4IB555JH0798/U6ZMKdsMAHQ/kQfANuMrX/lKqqqqstdee2XYsGFZvnx5tz329773vRx99NE544wzsueee2b69OlZtGhRRo0atdF9Zs2alaeffjpLly7ttjk2xw9+8IPMmjUrgwYNKsvzA9AzKkqlUqncQwDAturMM89MS0tL/umf/mmLPu/rr7+ePffcM48//nh22223LfrcAPQsZ/IAoIzOPffc7Lrrrt321tGuevnll3P11VcLPIACciYPAACgQJzJAwAAKBCRBwAAUCAiDwAAoEBEHgAAQIGIPAAAgAIReQAAAAUi8gAAAApE5AEAABSIyAMAACiQ/x+qqo2/DujRQQAAAABJRU5ErkJggg==", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# === Cell 13: Single-cell dynamic FBA (15 min, GLPK) with mechanistic QS & MazE/MazF ===\n", "import numpy as np, math, pandas as pd, logging, warnings\n", "from cobra import Reaction, Metabolite\n", "import matplotlib.pyplot as plt\n", "\n", "warnings.filterwarnings(\"ignore\")\n", "for name in (\"ME modelNone\",\"pytfa\",\"cobra\",\"optlang\"):\n", " try: logging.getLogger(name).setLevel(logging.ERROR)\n", " except Exception: pass\n", "\n", "def set_glpk(model):\n", " try: model.solver=\"glpk_exact\"; return \"glpk_exact\"\n", " except Exception: model.solver=\"glpk\"; return \"glpk\"\n", "\n", "# ---- robust EX resolver (uses your model’s EX_*_e ids) ----\n", "def ex_rxn_for(base_candidates):\n", " \"\"\"Return first exchange rxn id that exists from an ordered candidate list.\"\"\"\n", " ids = {r.id for r in etfl_model.reactions}\n", " for rid in base_candidates:\n", " if rid in ids:\n", " return rid\n", " return None\n", "\n", "EXIDS = dict(\n", " glc = ex_rxn_for([\"EX_glc__D_e\",\"EX_glc__D\",\"EX_glc_e\"]),\n", " o2 = ex_rxn_for([\"EX_o2_e\",\"EX_o2\"]),\n", " nh4 = ex_rxn_for([\"EX_nh4_e\",\"EX_nh4\"]),\n", " pi = ex_rxn_for([\"EX_pi_e\",\"EX_pi\"]),\n", " so4 = ex_rxn_for([\"EX_so4_e\",\"EX_so4\"]),\n", " cate = ex_rxn_for([\"EX_catechol_e\",\"EX_catechol\"]),\n", " dopa = ex_rxn_for([\"EX_dopa_e\",\"EX_L_DOPA_e\",\"EX_L_DOPA_c\"]),\n", " ahl = ex_rxn_for([\"EX_ahl_e\",\"EX_AHL_e\"]),\n", " co2 = ex_rxn_for([\"EX_co2_e\",\"EX_co2\"]),\n", " h2o = ex_rxn_for([\"EX_h2o_e\",\"EX_h2o\"])\n", ")\n", "\n", "def rxn_if_exists(rid):\n", " try: return etfl_model.reactions.get_by_id(rid)\n", " except Exception: return None\n", "\n", "# ---- realism: NGAM + ΔGAM_plasmid + basal MazE ----\n", "def enforce_realism(NGAM_ATP=8.39, dGAM_ATP=10.0, mazE_TL_LB=0.005):\n", " # ATPM\n", " def mid(x):\n", " for s in (\"_c\",\"_e\",\"\"):\n", " try: return etfl_model.metabolites.get_by_id(x+s)\n", " except: pass\n", " return None\n", " ATP,ADP,PI,H2O,H = map(mid, (\"atp\",\"adp\",\"pi\",\"h2o\",\"h\"))\n", " if all([ATP,ADP,PI,H2O,H]) and \"ATPM\" not in [r.id for r in etfl_model.reactions]:\n", " r=Reaction(\"ATPM\"); r.lower_bound=0.0; r.upper_bound=1000.0\n", " r.add_metabolites({ATP:-1.0,H2O:-1.0,ADP:+1.0,PI:+1.0,H:+1.0}); etfl_model.add_reactions([r])\n", " if \"ATPM\" in [r.id for r in etfl_model.reactions]:\n", " etfl_model.reactions.get_by_id(\"ATPM\").lower_bound = NGAM_ATP\n", " # ΔGAM plasmid inside biomass\n", " bio = next((r for r in etfl_model.reactions if \"biomass\" in (r.id+r.name).lower()), None)\n", " if bio and ATP and ADP and PI and H:\n", " cur = bio.metabolites.get(ATP, 0.0); target = cur - dGAM_ATP\n", " if abs(target-cur)>1e-9:\n", " bio.add_metabolites({ATP:-dGAM_ATP,ADP:+dGAM_ATP,PI:+dGAM_ATP,H:+dGAM_ATP})\n", " etfl_model.objective = bio.id\n", " # basal MazE burden\n", " r=rxn_if_exists(\"TL_mazE\")\n", " if r: r.lower_bound = mazE_TL_LB\n", "\n", "# ---- open gut exchanges ----\n", "def open_env_gut():\n", " for rid,lb in [(EXIDS[\"glc\"],-10.0),(EXIDS[\"o2\"],-1000.0),(EXIDS[\"nh4\"],-1000.0),\n", " (EXIDS[\"so4\"],-1000.0),(EXIDS[\"pi\"],-1000.0),(EXIDS[\"h2o\"],-1000.0),(EXIDS[\"co2\"],0.0)]:\n", " r = rxn_if_exists(rid); \n", " if r: r.lower_bound = lb\n", " set_temperature(37.0)\n", "\n", "# ---- Monod cap ----\n", "def monod(vmax, Ks, S_mM):\n", " return 0.0 if S_mM<=1e-6 else vmax*(S_mM/(Ks+S_mM))\n", "\n", "# ---- single-cell simulation (15 min) ----\n", "def simulate_single_cell_15min(seed=1, catechol_feed=0.0):\n", " np.random.seed(seed)\n", " # enforce realism & open gut\n", " enforce_realism(8.39,10.0,0.005)\n", " open_env_gut()\n", " # optionally allow catechol uptake\n", " if EXIDS[\"cate\"]:\n", " rxn_if_exists(EXIDS[\"cate\"]).lower_bound = float(catechol_feed)\n", "\n", " # initial external pools (mM)\n", " S = {\"glc\":10.0,\"o2\":1000.0,\"nh4\":100.0,\"pi\":50.0,\"so4\":50.0,\"cate\":max(0.0,-catechol_feed)}\n", "\n", " # initialize mechanistic states\n", " qs_state = qs_init_state()\n", " ta_state = mazef_init_state()\n", "\n", " # time grid\n", " T_end_min = 15; dt_sec = 30\n", " dt_h = dt_sec/3600.0; steps = int(T_end_min*60/dt_sec)\n", " AHL_ext = 0.0 # well-mixed approximation\n", " X = 0.005 # gDW\n", " rows=[]\n", "\n", " for k in range(steps+1):\n", " t_h = k*dt_h\n", "\n", " # mechanistic regulation step (QS & MazE/MazF) -> pushes TX_tpl UB + MazF cleavage LB\n", " qs_state, ta_state, act, enforced = mech_regulation_step(\n", " qs_state, ta_state, X_gDW=X, AHL_ext_mM=AHL_ext, t_h=t_h, dt_h=dt_h,\n", " use_flow=False, flow_rate=0.0\n", " )\n", "\n", " # Monod set on glc & o2\n", " for key, (rid, vmax, Ks) in dict(\n", " glc=(EXIDS[\"glc\"],10.0,0.1),\n", " o2 =(EXIDS[\"o2\"],1000.0,0.01),\n", " ).items():\n", " r = rxn_if_exists(rid)\n", " if r:\n", " r.lower_bound = -monod(vmax, Ks, S[key])\n", "\n", " # solve\n", " set_glpk(etfl_model)\n", " sol = etfl_model.optimize()\n", " mu = float(sol.objective_value or 0.0)\n", "\n", " # update AHL_ext from synth/deg/ex (use AHL_SYN and EX_ahl if present)\n", " ahl_syn = float(sol.fluxes.get(\"AHL_SYN\", 0.0)) if \"AHL_SYN\" in [r.id for r in etfl_model.reactions] else 0.0\n", " ahl_ex = float(sol.fluxes.get(EXIDS[\"ahl\"],0.0)) if EXIDS[\"ahl\"] else 0.0\n", " AHL_ext = max(0.0, AHL_ext + dt_h*(ahl_syn - 0.2*AHL_ext - max(0.0,ahl_ex)))\n", "\n", " # update external GLU & O2 pools (mM): ∆S = v*X*dt / V; here V=1 mL = 1e-3 L\n", " V_L = 1e-3\n", " for key,rid in ((\"glc\",EXIDS[\"glc\"]),(\"o2\",EXIDS[\"o2\"])):\n", " r = rxn_if_exists(rid)\n", " if r:\n", " v = float(sol.fluxes.get(r.id, 0.0))\n", " if v<0:\n", " S[key] = max(0.0, S[key] + (v*X*dt_h)/V_L)\n", "\n", " # read L-DOPA export\n", " dopa_ex = 0.0\n", " if EXIDS[\"dopa\"]:\n", " dopa_ex = float(sol.fluxes.get(EXIDS[\"dopa\"],0.0))\n", "\n", " rows.append({\"t_min\":t_h*60, \"mu\":mu, \"AHL_ext\":AHL_ext, \"glc_mM\":S[\"glc\"], \"o2_mM\":S[\"o2\"], \"ldopa_ex\":dopa_ex})\n", "\n", " df = pd.DataFrame(rows)\n", " display(df.head())\n", " out = RES/\"single_cell_15min_mech.csv\"\n", " df.to_csv(out, index=False); print(\"Saved:\", out)\n", " # plot\n", " fig,axs=plt.subplots(2,1,figsize=(9,7),sharex=True)\n", " axs[0].plot(df.t_min, df.mu, label=\"μ\"); axs[0].set_ylabel(\"μ (h⁻¹)\"); axs[0].legend()\n", " axs[1].plot(df.t_min, df.ldopa_ex, c=\"brown\", label=\"L-DOPA ex\"); axs[1].legend(); axs[1].set_xlabel(\"time (min)\")\n", " plt.tight_layout(); plt.savefig(RES/\"single_cell_15min_mech.png\", dpi=160); plt.show()\n", "\n", "simulate_single_cell_15min(seed=7, catechol_feed=0.0) # set catechol_feed=-5.0 for feeding\n" ] }, { "cell_type": "code", "execution_count": 109, "id": "bf03c1bd-aa38-4784-89e3-0ffd5bdb1c8c", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Temperature unchanged (T=37.0°C).\n" ] }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
\n", "
" ], "text/plain": [ "Empty DataFrame\n", "Columns: []\n", "Index: []" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "image/png": "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tm1by7n69esrMTFRTz/9tAoKChzWHthGVhiHTijUuKeeekpLly7VggULNG7cOEnS+PHj1a5dO3333XeVusbq1au1d+9ejRkzxuHtq1evnn7//XetXr26zHvLli2Tj49PufUefPBBvf7661XqTINjlc7dtucAYG3ZsmVq3ry5tm7dqv379zu7OTpx4oTefvttPfTQQ4Zc38fHR8nJyWXOb9y4Ub/++qu8vb3LvPfQQw9px44dWr9+vSFtgmORFYDjLViwQEuXLtUrr7yiUaNG6dSpUxoxYoQ6d+6sw4cPlyn/6KOPqn///srMzNTjjz+uV199VbGxsXr11VfVoUMH7d27t0wdb29vLV26VEuXLtUzzzyjoKAgPfrooxo6dKhVObPZrPfee0/NmzfX6tWrq/Rv83Pnzunll1/WqFGj5OnpWfUfhA0VZczPP/+szZs3l/t7xvDhw3Xy5Mly68E4ZIVx6IRCjevTp4/uv/9+DR8+XJMnT9batWu1bt06HT9+XP/3f/9X7gikiy1evFhdu3bVFVdc4fD2eXt7q2fPnnrvvffKvJecnKx+/fqVWy8+Pl6FhYVauXKlw9uEyik2e9h9APjDwYMHtXnzZr344otq0qRJrZia8O6776pevXrq37+/Idfv27evVq5cqfPnz1udT05OVlRUlEJDQ8vUadOmjdq2baslS5YY0iY4FlkBON7dd9+t+++/XyNHjtS0adP01Vdf6d1339WuXbt0zz33WJV97733NGfOHA0cOFAZGRmaOHGiRo0apddee02bNm3S6dOndc8995T5Hq5Xr57uv/9+3X///UpISFBaWpo6deqkFStW6OjRo5ZyGzZs0K+//qq33npL58+f14cffljp+1izZo1OnDihe++9174fSAX69u2r1NTUMiOBk5OTFRISok6dOpWpExgYqF69epExNYysMA4/GTeyYcMGderUST4+Prrqqqv0+uuvW4bI2pKdna0JEyaoefPm8vb21pVXXqkHHnig2lMlqurWW2/V1KlT9csvv1Q4RLVUQUGBUlJSFBsbW+a90ikhK1eu1LXXXitfX1/FxMTo+++/lyS9/vrratmypXx8fNS9e3f9/PPP5X7Gfffdp88//1zZ2dmWc9u2bdO+fft03333lVsnODhY7du318cff1y5mwaAWm7ZsmW6/PLL1a9fP9199921ohNq1apVio6OLjMVu3v37mrbtq2+++473XLLLbrsssvUsmVL/etf/5J0YSRTdHS0fH191apVK61bt67c6w8ePFi//fabUlNTLeeKior0r3/9q8Lvf0m67bbbtHr1apnNZgfcJQC4viFDhmjUqFHasmWL1Xfqk08+qcsvv1xvvPFGmdFGnTt31uOPP67vv//e8v1dEQ8PD3Xv3l2SrP5Nv2zZMl177bXq0aOHYmNjq5Rdq1atUvPmzXXVVVdZnR82bJgaNmyoQ4cO6fbbb1fDhg11xRVXaP78+ZKk77//XrfeeqsaNGigZs2aVThq6Y477pC3t3eZh9bJycm69957Kxx9ddttt+nLL7/UqVOnKn0vQG1FJ5Sb+Oabb9S7d2/99ttvevLJJzVy5Eg99dRTWrVqlc26eXl5+stf/qJXXnlFvXr10ssvv6yHHnpIe/bs0a+//mp84//nr3/9qyTp3//+9yXLZWRkqKioSDfccEO57//nP//RI488oqFDh2rGjBnavXu3br/9ds2fP1/z5s3T3//+dz322GNKT0/XiBEjyr3GXXfdJZPJZPXkJDk5Wa1bt67wcyUpKipKmzdvtnWrMEiJTCqRhx0Hw2aBP1u2bJnuuusueXl5afDgwdq3b5+2bdtWbtmCggKdPHmyzOHIzSPOnTunbdu2Vfg9fPr0ad1+++2Kjo7W7Nmz5e3trUGDBmnFihUaNGiQ+vbtq2effVb5+fm6++67y52i0bx5c8XExFiNhv3888+Vk5NzyfVBoqKilJ2drR9++MH+G4WhyAqg5lz87/t9+/Zp7969uuOOO+Tv719unQceeEDShVFJthw4cEDShfX5JKmwsFAffPCBBg8eLOnCg4X169crMzOzUu3dvHlzhRlTXFysPn36KCIiQrNnz1bz5s2VkJCgJUuWqHfv3urUqZOee+45+fn56YEHHtDBgwfLXOOyyy7THXfcYZUx3377rX744YdLPuiIioqS2Wzm94waRFYYp56zGwDHmD59ujw9PfXVV18pPDxcknTvvfeqTZs2Nus+//zz2rVrlz788EPdeeedlvNTpkyp0Se6V155pQICAixhUpE9e/ZIkiIjI8t9f+/evdqzZ4+aN28uSbr88sv14IMPatasWfrpp5/k5+cn6UKQJCUl6eeff7aULeXn56fbb79dycnJGjFihEpKSrR8+XL97W9/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jWUHwUvJyMiQyWTi9wy4BRYmdxMzZszQ+fPn1bVrV82ePVtJSUm65ZZbKrVDz2OPPaZrr71W99xzj8aMGaPXX39dSUlJiomJueRQ2er6/PPP9e6772rJkiV67rnnFBcXp9jYWIWEhOiTTz6Rj4/PJev7+PioV69eWrduncPbdjEPDw9NmTLF5q540oW1ub777rsKd9SA8UrnbttzVMWmTZvUv39/hYeHy2QyadWqVVbvm81mTZs2TWFhYfL19VVsbKz27dt3yWs2b95cJpOpzDF27FhLme7du5d5/6GHHqpS24GKfPLJJzpz5kyFnfw33XSTmjRpUqlFXm158cUXNWvWLKvjmWeeuWSdO+64Q1u3bi2zYK0Rhg4dqunTp1dqxFdqaqr69+/Peh0uoKazotT8+fPVvHlz+fj4KDo6Wlu3br1k+ZUrV6p169by8fFRu3bt9Nlnn1m9X15WmEwmPf/885Yy5WXKs88+W632w/299dZbZb6TZ82aZXP9Jkn617/+pXfffVdvvfWWZs6cqW7dumnIkCFq166dVq5caVV2yJAhevjhh5WcnKxOnTrphRde0KJFizR27Fh169ZNgYGB+te//qX69etXuu3Jyckym80VZlffvn1Vr149m9l1xx136PDhw/rpp58q/dnVdccdd2jGjBkKCwuzWTY1NVVdu3a1TEuH8cgK47KCkVBuIioqSp9//rkeffRRTZ06VREREXrqqae0e/du7dmz55J1GzZsqP/85z+aPn26PvroI7399tsKDg5Wz549y11zyV7Tpk2TJHl5eSkoKEjt2rXT3LlzNXz4cJs7ZZQaMWKE4uPjLVub1gYffvihvL29rXbHQM0qkYdKanDYbH5+vjp06KARI0borrvuKvP+7NmzNW/ePL399tuKjIzU1KlTFRcXpx9//LHCztZt27ZZ7Ty2a9cu3Xbbbbrnnnusyo0ePVpPPfWU5fVll11WpbYDFVm2bJl8fHx02223lfu+h4eHZaeh3377za5/ECclJZU55+npqSeeeKLCOn/96181adIkffLJJ7r//vur/dmOtGfPHu3atUtz5851dlNQCTWdFZK0YsUKJSYmauHChYqOjtbcuXMVFxenvXv3lrshy+bNmzV48GAlJSXp9ttvV3JysgYMGKAdO3ZYHjAeO3bMqs7nn3+ukSNHlhk98tRTT2n06NGW15X9txbqngULFpR7ftiwYTb/uyl9YOvj46PGjRurY8eOeuutt3TffffJ29u7TPm5c+eqR48emj9/vp555hn9/vvvioiI0NixYzVp0qQqr320bNkyNW3aVB06dCj3/cDAQHXr1k0rVqzQiy++qHr1yv81uH///mrcuLHef/99TZkypUptMEpOTo7+/e9/67XXXnN2U+oUssK4rDCZL7ViGlzegAED9MMPP9gcfeFqiouLde211+ree+/VzJkznd0cSdL111+v7t2766WXXnJ2U+qc3NxcBQQEKHlnW13mZ3unlor8fqZY93XcpZycHPn7+1eprslk0kcffaQBAwZIujAKKjw8XI888ogeffRRSRf+ERESEqIlS5ZUao0xSRo/frzWrFmjffv2WUZYdO/eXR07duQXXtRZI0eO1E8//aT//Oc/zm6KpAt/Tzdt2mSZLoHayZlZER0drRtvvFGvvvqqJKmkpEQREREaN26cJk2aVKb8wIEDlZ+frzVr1ljO3XTTTerYsaMWLlxY7mcMGDBAZ86cUVpamuVc8+bNNX78eI0fP74KdwjUbTNnztTixYu1b9++Su0AaLS5c+dq9uzZOnDgQI2vxVgXkRXGYzqeGzl79qzV63379umzzz5T9+7dndMgA3l6euqpp57S/PnzLVu/OlNKSor27dunyZMnO7spdVqx2WT3IV0Inz8fhYWFVW7LwYMHlZmZabWGQkBAgKKjo5Wenl6paxQVFendd9/ViBEjyvxiu2zZMjVu3Fht27bV5MmT9fvvv1e5jYCrmj59urZt26avvvrK2U3Rb7/9pjfffFOzZs2iA8pF1HRWFBUVKSMjwyoPPDw8FBsbW2EepKenl1mDJy4ursLyWVlZ+vTTTzVy5Mgy7z377LNq1KiRrr/+ej3//PM6f/58pX5OQF01YcIE5eXllbs7bE07d+6cXnzxRU2ZMoUOqBpGVhiXFUzHcyMtWrTQsGHD1KJFC/3yyy9asGCBvLy8NHHiRLuue+LECavpQRcrKiqSl5fXJa/RpEkThz9JGDhwYI0viluR3r1714rOsLqu2M5dLIr/N2z24ime06dP14wZM6p0rczMTElSSEiI1fmQkBDLe7asWrVK2dnZGjZsmNX5++67T82aNVN4eLi+++47Pf7449q7d68+/PDDKrURcFVNmzZVQUGBs5shSWrUqBHf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sIWsAAD34/BOqM2bN+uOO+5Qv379JEnNmzfXe++9p61btzr6owDACrtYuA6yAoCzkBWug6wA4CxkhXEcPh2vS5cuSktL008//SRJ+vbbb/Xll1+qT58+jv4oALBS8r8FBO05UDPICgDOQla4DrICgLOQFcZx+EioSZMmKTc3V61bt5anp6eKi4v19NNPa8iQIeWWLywsVGFhoeV1bm6uo5sEAKhlyAoAgC1kBQC4H4ePhHr//fe1bNkyJScna8eOHXr77bf1wgsv6O233y63fFJSkgICAixHRESEo5sEoI4wm+0/UDPICgDOQla4DrICgLOQFcZx+Eioxx57TJMmTdKgQYMkSe3atdMvv/yipKQkDR06tEz5yZMnKzEx0fI6NzeXwABQLczddh1kBQBnIStcB1kBwFnICuM4vBPq999/l4eH9QArT09PlZSUlFve29tb3t7ejm4GgDqIsHAdZAUAZyErXAdZAcBZyArjOLwTqn///nr66afVtGlTXXfddfrmm2/04osvasSIEY7+KACAiyIrAAC2kBUA4H4cvibUK6+8orvvvlt///vf1aZNGz366KN68MEHNXPmTEd/FABYqeldLDZt2qT+/fsrPDxcJpNJq1atsnrfbDZr2rRpCgsLk6+vr2JjY7Vv375LXjMpKUk33nij/Pz8FBwcrAEDBmjv3r1WZbp37y6TyWR1PPTQQ1Vqu7ORFQCcxVk7Hs2fP1/NmzeXj4+PoqOjtXXr1kuWX7lypVq3bi0fHx+1a9dOn332meW9c+fO6fHHH1e7du3UoEEDhYeH64EHHtDRo0etrtG8efMyefHss89Wq/3OQFYAcBaywriscHgnlJ+fn+bOnatffvlFZ8+e1YEDBzRr1ix5eXk5+qMAwEpNLyCYn5+vDh06aP78+eW+P3v2bM2bN08LFy7Uli1b1KBBA8XFxamgoKDCa27cuFFjx47V119/rdTUVJ07d069evVSfn6+VbnRo0fr2LFjlmP27NlVa7yTkRUAnMUZi82uWLFCiYmJmj59unbs2KEOHTooLi5Ox48fL7f85s2bNXjwYI0cOVLffPONBgwYoAEDBmjXrl2SLkxT27Fjh6ZOnaodO3boww8/1N69e/V///d/Za711FNPWeXFuHHjqn4DTkJWAHAWssK4rHD4dDwAqCv69OmjPn36lPue2WzW3LlzNWXK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k0/q448/tgqTPn36WP7cvn17RUdHq1mzZnr//fc1cuTIatwYAMCihrNi0qRJeu655y55yd27d9vRoMpLT0/X7t27tXTpUqvzrVq1UqtWrSyvu3TpogMHDuill14qUxYA6gSywrCsoBMKAC5Sle1kr7rqKm3cuFH5+fnKzc1VWFiYBg4cqBYtWlyy3vLlyzVq1CitXLlSsbGxlywbGBioa665Rvv376/0PQAAjFXZrHjkkUc0bNiwS5Zp0aKFQkNDLTsQlTp//rxOnTpV4RqBoaGhKioqUnZ2ttUT7qysrHLrvPnmm+rYsaOioqJstrtz585sigEAdiIryqITCoDbsHc7VHvqNmjQQA0aNNDp06e1du1azZ49u8Ky7733nkaMGKHly5erX79+Nq+dl5enAwcO6K9//Wu12wcAuKCms6JJkyZq0qSJzXIxMTHKzs5WRkaG5R/+69evV0lJiaKjo8utExUVpfr16ystLU3x8fGSLuxadOjQIcXExFiVzcvL0/vvv1/pqSA7d+5UWFhYpcoCgLshK4zLCpddE2r+/Plq3ry5fHx8FB0dra1btzq7SWUkJSXpxhtvlJ+fn4KDgzVgwADt3bvX2c2y6dlnn5XJZNL48eOd3ZQyjhw5ovvvv1+NGjWSr6+v2rVrp+3btzu7WWUUFxdr6tSpioyMlK+vr6666irNnDlTzt4HYNOmTerfv7/Cw8NlMpm0atUqq/fNZrOmTZumsLAw+fr6KjY2Vvv27XNOY6vDCVuprl27VikpKTp48KBSU1PVo0cPtW7dWsOHD5ckTZ48WQ888IClfHJysh544AHNmTNH0dHRyszMVGZmpnJycixlHn30UW3cuFE///yzNm/erDvvvFOenp4aPHiw/T+jOoasMA5ZYT+ywklq6bbbbdq0Ue/evTV69Ght3bpVX331lRISEjRo0CDLbkdHjhxR69atLd9lAQEBGjlypBITE/XFF18oIyNDw4cPV0xMjG666Sar669YsULnz5/X/fffX+az586dq48//lj79+/Xrl27NH78eK1fv15jx4415F5rG7LCOGSF/cgKJyEryny2o7LCJTuhVqxYocTERE2fPl07duxQhw4dFBcXV2ZYmrNt3LhRY8eO1ddff63U1FSdO3dOvXr1Un5+vrObVqFt27bp9ddfV/v27Z3dlDJOnz6trl27qn79+vr888/1448/as6cObr88sud3bQynnvuOS1YsECvvvqqdu/ereeee06zZ8/WK6+84tR25efnq0OHDpo/f36578+ePVvz5s3TwoULtWXLFjVo0EBxcXEqKCio4Za6jpycHI0dO1atW7fWAw88oG7dumnt2rWqX7++JOnYsWM6dOiQpfwbb7yh8+fPa+zYsQoLC7McDz/8sKXMr7/+qsGDB6tVq1a699571ahRI3399deVejqCP5AVxiErHIOswMWWLVum1q1bq2fPnurbt6+6deumN954w/L+uXPntHfvXv3++++Wcy+99JJuv/12xcfH6+abb1ZoaKg+/PDDMtdetGiR7rrrrnK31S4qKtIjjzyidu3a6ZZbbtG3335bZudXd0VWGIescAyyAhdz9awwmZ3dhVoN0dHRuvHGG/Xqq69KurDFeUREhMaNG6dJkyY5uXUVO3HihIKDg7Vx40bdfPPNzm5OGXl5ebrhhhv02muvadasWerYsaPmzp3r7GZZTJo0SV999ZX+85//OLspNt1+++0KCQnRokWLLOfi4+Pl6+urd99914kt+4PJZNJHH32kAQMGSLrwtCI8PFyPPPKIHn30UUkXOlhCQkK0ZMkSDRo0yImtvbTSrVRjrxpv91aq6w7MVU5OTqXXhELtRVYYg6xwHLKiZpEVKA9ZYQyywnHIippFVhjP5UZCFRUVKSMjw2ohXw8PD8XGxio9Pd2JLbOtdLpNUFCQk1tSvrFjx6pfv342F0l2lk8++USdOnXSPffco+DgYF1//fX65z//6exmlatLly5KS0vTTz/9JEn69ttv9eWXX1rtelbbHDx4UJmZmVb//wcEBCg6OrrW/92yqKXDZlHzyArjkBWOQ1Y4CVmB/yErjENWOA5Z4SRkhWFcbmHykydPqri4WCEhIVbnQ0JCtGfPHie1yraSkhKNHz9eXbt2Vdu2bZ3dnDKWL1+uHTt2aNu2bc5uSoX++9//asGCBUpMTNQTTzyhbdu26R//+Ie8vLw0dOhQZzfPyqRJk5Sbm6vWrVvL09NTxcXFevrppzVkyBBnN61CmZmZklTu363S92o/e7/wCQt3QVYYg6xwLLLCWcgKXEBWGIOscCyywlnICqO4XCeUqxo7dqx27dpVK7e6PXz4sB5++GGlpqbKx8fH2c2pUElJiTp16qRnnnlGknT99ddr165dWrhw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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# === Cell 14: Spatial 2-D ABM + gut flow + mechanistic QS & MazE/MazF (GLPK, fast) ===\n", "import numpy as np, pandas as pd, logging, warnings, math\n", "from cobra import Reaction, Metabolite\n", "import matplotlib.pyplot as plt\n", "\n", "warnings.filterwarnings(\"ignore\")\n", "for name in (\"ME modelNone\",\"pytfa\",\"cobra\",\"optlang\"):\n", " try: logging.getLogger(name).setLevel(logging.ERROR)\n", " except Exception: pass\n", "\n", "def set_glpk(model):\n", " try: model.solver=\"glpk_exact\"; return \"glpk_exact\"\n", " except Exception: model.solver=\"glpk\"; return \"glpk\"\n", "\n", "# re-use EXIDS/rxn_if_exists/enforce_realism/open_env_gut from Cell 13\n", "# (they’re in the same kernel; if not, copy them here)\n", "\n", "# grid/time small enough to finish ≲10 min\n", "grid=(12,12); dx=1.0\n", "dt_h = 3.0/60.0 # 3 min\n", "steps = 20 # 1 h total\n", "N_agents=9\n", "V_voxel_L = 1e-3 # 1 mL per cell\n", "\n", "# fields mM\n", "species=[\"glc\",\"o2\",\"catechol\",\"AHL\",\"DOPA\"]\n", "sidx={sp:i for i,sp in enumerate(species)}\n", "F=np.zeros((len(species),grid[0],grid[1]),dtype=float)\n", "F[sidx[\"glc\"]]=10.0; F[sidx[\"o2\"]]=1000.0; F[sidx[\"catechol\"]]=0.0\n", "D={\"glc\":0.5, \"o2\":1.0, \"catechol\":0.3, \"AHL\":0.2, \"DOPA\":0.4}\n", "\n", "# gut flow\n", "USE_FLOW_ENV=True; flow_rate=0.05\n", "S_in={\"glc\":10.0,\"o2\":1000.0,\"catechol\":0.0}\n", "\n", "# agents\n", "rng=np.random.default_rng(17)\n", "coords=list(zip(rng.integers(0,grid[0],N_agents), rng.integers(0,grid[1],N_agents)))\n", "agents=[]\n", "for cid,(x,y) in enumerate(coords):\n", " agents.append({\"id\":cid,\"x\":int(x),\"y\":int(y),\n", " \"X\":0.005, # gDW\n", " \"qs\":qs_init_state(), \"ta\":mazef_init_state(),\n", " \"alive\":True})\n", "\n", "# enforce realism & open env once\n", "enforce_realism(8.39,10.0,0.005); open_env_gut()\n", "\n", "def diffuse(F,D,dt):\n", " G=F.copy()\n", " for sp,dif in D.items():\n", " k=sidx[sp]; a=F[k]; lap=np.zeros_like(a)\n", " lap[1:-1,1:-1]=(a[:-2,1:-1]+a[2:,1:-1]+a[1:-1,:-2]+a[1:-1,2:]-4*a[1:-1,1:-1])\n", " G[k]+=dif*lap*dt/(dx**2); G[k]=np.clip(G[k],0,None)\n", " return G\n", "\n", "trace=[]\n", "for it in range(steps+1):\n", " t=it*dt_h\n", " # diffuse\n", " F=diffuse(F,D,dt_h)\n", " # flow\n", " if USE_FLOW_ENV:\n", " for sp in (\"glc\",\"o2\",\"catechol\"):\n", " F[sidx[sp]] += flow_rate*(S_in[sp]-F[sidx[sp]])*dt_h\n", " F[sidx[sp]] = np.clip(F[sidx[sp]],0.0,None)\n", "\n", " for a in agents:\n", " if not a[\"alive\"]: continue\n", " x,y=a[\"x\"],a[\"y\"]; X=a[\"X\"]\n", "\n", " # mechanistic step (uses extracellular AHL at voxel)\n", " AHL_ext=float(F[sidx[\"AHL\"],x,y])\n", " a[\"qs\"], a[\"ta\"], act, enforced = mech_regulation_step(\n", " a[\"qs\"], a[\"ta\"], X_gDW=X, AHL_ext_mM=AHL_ext, t_h=t, dt_h=dt_h,\n", " use_flow=USE_FLOW_ENV, flow_rate=flow_rate\n", " )\n", "\n", " # Monod caps from local pools\n", " caps = {\n", " EXIDS[\"glc\"]: (10.0,0.1, float(F[sidx[\"glc\"],x,y])),\n", " EXIDS[\"o2\"]: (1000.0,0.01,float(F[sidx[\"o2\"],x,y])),\n", " EXIDS[\"cate\"]: (5.0,0.1, float(F[sidx[\"catechol\"],x,y])),\n", " EXIDS[\"nh4\"]: (1000.0,0.01,100.0),\n", " EXIDS[\"pi\"]: (1000.0,0.01,50.0),\n", " EXIDS[\"so4\"]: (1000.0,0.01,50.0)\n", " }\n", " pushed=[]\n", " for rid,(vmax,Ks,S) in caps.items():\n", " if not rid: continue\n", " r=rxn_if_exists(rid); \n", " if not r: continue\n", " before=(r.lower_bound,r.upper_bound)\n", " vmax_eff = 0.0 if S<=1e-6 else vmax*(S/(Ks+S))\n", " r.lower_bound = -vmax_eff; pushed.append((r,before))\n", "\n", " # solve LP\n", " set_glpk(etfl_model)\n", " sol=etfl_model.optimize()\n", " if sol.status!=\"optimal\":\n", " for r,b in pushed: r.lower_bound,r.upper_bound=b\n", " a[\"alive\"]=False; \n", " continue\n", "\n", " mu=float(sol.objective_value or 0.0)\n", "\n", " # AHL synthesis & L-DOPA export\n", " ahl_syn=float(sol.fluxes.get(\"AHL_SYN\",0.0)) if \"AHL_SYN\" in [r.id for r in etfl_model.reactions] else 0.0\n", " dopa_ex=0.0\n", " if EXIDS[\"dopa\"]: dopa_ex=float(sol.fluxes.get(EXIDS[\"dopa\"],0.0))\n", "\n", " # update voxel pools (mM) using v*X*dt/V\n", " for rid,key in ((EXIDS[\"glc\"],\"glc\"), (EXIDS[\"o2\"],\"o2\"), (EXIDS[\"cate\"],\"catechol\")):\n", " r=rxn_if_exists(rid)\n", " if not r: continue\n", " v=float(sol.fluxes.get(r.id,0.0))\n", " if v<0:\n", " F[sidx[key],x,y]=max(0.0, F[sidx[key],x,y] + (v*X*dt_h)/V_voxel_L)\n", " F[sidx[\"AHL\"], x,y] += max(0.0,ahl_syn)*dt_h/V_voxel_L\n", " F[sidx[\"DOPA\"],x,y] += max(0.0,dopa_ex)*dt_h/V_voxel_L\n", "\n", " # restore bounds\n", " for r,b in pushed: r.lower_bound,r.upper_bound=b\n", "\n", " # biomass update (quasi-exponential)\n", " a[\"X\"]=max(1e-9, X*(1.0 + mu*dt_h))\n", " trace.append({\"t_min\":t*60,\"cell\":a[\"id\"],\"x\":x,\"y\":y,\"mu\":mu,\"X\":a[\"X\"],\"DOPA_ex\":dopa_ex})\n", "\n", "# save + fields snapshot\n", "abm_df=pd.DataFrame(trace); display(abm_df.head())\n", "abm_df.to_csv(RES/\"abm_spatial_gut_mech.csv\", index=False)\n", "\n", "fig,axes=plt.subplots(1,3,figsize=(12,4))\n", "for ax, sp, title in zip(axes,[\"glc\",\"AHL\",\"DOPA\"],[\"glc__D (mM)\",\"AHL (mM)\",\"L-DOPA (mM)\"]):\n", " im=ax.imshow(F[sidx[sp]],origin='lower',cmap='viridis'); ax.set_title(title); plt.colorbar(im,ax=ax)\n", "plt.tight_layout(); plt.savefig(RES/\"abm_fields_gut_mech.png\",dpi=160); plt.show()\n" ] }, { "cell_type": "code", "execution_count": 110, "id": "16aefa23-ed6d-4157-88f7-e670654cc99f", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['EX_12dgr160_e',\n", " 'EX_12dgr180_e',\n", " 'EX_13dampp_e',\n", " 'EX_15dap_e',\n", " 'EX_1ag160_e',\n", " 'EX_1ag180_e',\n", " 'EX_1ag181d9_e',\n", " 'EX_1ag182d9d12_e',\n", " 'EX_25dkglcn_e',\n", " 'EX_26dap__M_e',\n", " 'EX_AEP_e',\n", " 'EX_2ddglcn_e',\n", " 'EX_2dhglcn_e',\n", " 'EX_2m35mdntha_e',\n", " 'EX_34dhbz_e',\n", " 'EX_34dhcinm_e',\n", " 'EX_34dhphe_e',\n", " 'EX_35dnta_e',\n", " 'EX_3h4atb_e',\n", " 'EX_3mb_e',\n", " 'EX_btd_RR_e',\n", " 'EX_btn_e',\n", " 'EX_butso3_e',\n", " 'EX_bz_e',\n", " 'EX_ca2_e',\n", " 'EX_carn_e',\n", " 'EX_catechol_e',\n", " 'EX_cbi_e',\n", " 'EX_cbl1_e',\n", " 'EX_cd2_e',\n", " 'EX_cell4_e',\n", " 'EX_cgly_e',\n", " 'EX_chol_e',\n", " 'EX_chols_e',\n", " 'EX_chor_e',\n", " 'EX_cinnm_e',\n", " 'EX_cit_e',\n", " 'EX_cl_e',\n", " 'EX_cm_e',\n", " 'EX_cmcbtt_e',\n", " 'EX_co2_e',\n", " 'EX_co_e',\n", " 'EX_cobalt2_e',\n", " 'EX_confrl_e',\n", " 'EX_creat_e',\n", " 'EX_crn_e',\n", " 'EX_cro2_e',\n", " 'EX_cro4_e',\n", " 'EX_crtn_e',\n", " 'EX_csn_e',\n", " 'EX_cu2_e',\n", " 'EX_cu_e',\n", " 'EX_cyan_e',\n", " 'EX_cys__D_e',\n", " 'EX_cys__L_e',\n", " 'EX_dag181d9_e',\n", " 'EX_dag182d9d12_e',\n", " 'EX_dca_e',\n", " 'EX_ddca_e',\n", " 'EX_dgudbutn_e',\n", " 'EX_dmanur_e',\n", " 'EX_dmgly_e',\n", " 'EX_dmso2_e',\n", " 'EX_dopa_e',\n", " 'EX_ecto__L_e',\n", " 'EX_enter_e',\n", " 'EX_etha_e',\n", " 'EX_ethso3_e',\n", " 'EX_etoh_e',\n", " 'EX_fald_e',\n", " 'EX_fcmcbtt_e',\n", " 'EX_fe2_e',\n", " 'EX_fe3_e',\n", " 'EX_fe3dcit_e',\n", " 'EX_fe3mcbtt_e',\n", " 'EX_fe3pyovd_e',\n", " 'EX_fe3pyovd_kt_e',\n", " 'EX_fecrm_e',\n", " 'EX_fecrm_un_e',\n", " 'EX_feenter_e',\n", " 'EX_feoxam_e',\n", " 'EX_feoxam_un_e',\n", " 'EX_fer_e',\n", " 'EX_for_e',\n", " 'EX_fru_e',\n", " 'EX_fum_e',\n", " 'EX_ga_e',\n", " 'EX_galct__D_e',\n", " 'EX_galur_e',\n", " 'EX_glc__D_e',\n", " 'EX_glcn_e',\n", " 'EX_glcr_e',\n", " 'EX_glcur_e',\n", " 'EX_gln__L_e',\n", " 'EX_glu__L_e',\n", " 'EX_glutar_e',\n", " 'EX_gly_e',\n", " 'EX_glyald_e',\n", " 'EX_glyb_e',\n", " 'EX_glyc__R_e']" ] }, "execution_count": 110, "metadata": {}, "output_type": "execute_result" } ], "source": [ "[r.id for r in etfl_model.reactions if r.id.startswith(\"EX_\")][:100]\n" ] }, { "cell_type": "code", "execution_count": 111, "id": "1263f535-b0ec-434f-8a42-bdd9d478db4b", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Loaded FBA scenario table.\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", "
envscenariostatussolvergrowthldopa_exATP_totalGTP_total
0in_vivo_gutWT no TPLoptimalglpk_exact0.00.07.6442NaN
1in_vivo_gutWT + TPL (no catechol)optimalglpk_exact0.00.07.6442NaN
2in_vivo_gutTPL + KOs (no catechol)optimalglpk_exact0.00.07.6442NaN
3in_vivo_gutWT + TPL (catechol feed)optimalglpk_exact0.00.07.6442NaN
4in_vivo_gutTPL + KOs (catechol feed)optimalglpk_exact0.00.07.6442NaN
\n", "
" ], "text/plain": [ " env scenario status solver growth \\\n", "0 in_vivo_gut WT no TPL optimal glpk_exact 0.0 \n", "1 in_vivo_gut WT + TPL (no catechol) optimal glpk_exact 0.0 \n", "2 in_vivo_gut TPL + KOs (no catechol) optimal glpk_exact 0.0 \n", "3 in_vivo_gut WT + TPL (catechol feed) optimal glpk_exact 0.0 \n", "4 in_vivo_gut TPL + KOs (catechol feed) optimal glpk_exact 0.0 \n", "\n", " ldopa_ex ATP_total GTP_total \n", "0 0.0 7.6442 NaN \n", "1 0.0 7.6442 NaN \n", "2 0.0 7.6442 NaN \n", "3 0.0 7.6442 NaN \n", "4 0.0 7.6442 NaN " ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "image/png": "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ddJNmTJFihQpInp6ekq77d+/X1q2bCk2NjZiaGgoNjY20qlTJ7l27VqGbbR9+3ZxdnYWY2NjcXBwkBkzZsgvv/yS5t9k+/btUqNGDTExMZE8efJI1apVZd26danaOy1PnjyRnj17SoECBcTQ0FCcnJxk1apVOmn+/PNPadCggVhbW4uhoaHY2dlJ37595dGjR0qaH374QapWrSp58+YVExMTKVu2rEydOlV57Fh63nW7ixcvSuvWrSVv3rxibGwsZcqUkYkTJ6bal4EDB4qtra0YGBhIoUKFpG7durJs2TIljfZRVX/88YfOtiEhIQJAZ98vX74s9erVk9y5c0uBAgXkq6++kn///TdVuu7du4uZmVma+/fmo6pERKKiomT48OFiY2MjBgYGUqpUKZk1a5bOo7c+5NghIqK304i8w/gsIiIiStO8efMwfPhw3L9/H0WKFMnq6hAREdFHwuCZiIjoHb169UpncrTY2FhUqlQJSUlJyqRlRERE9GniPc9ERETvqE2bNrCzs4OLiwsiIiLw+++/48qVK/Dz88vqqhEREdFHxuCZiIjoHTVs2BArVqyAn58fkpKS4OjoiPXr12fqhGlERESUNThsm4iIiIiIiCgDfM4zERERERERUQY+62HbycnJePjwIczNzZXncxIREREREdHnQUQQFRUFGxsb6Om9vW/5sw6eHz58CFtb26yuBhEREREREWWhe/fuoWjRom9N81kHz+bm5gBeN1SePHmyuDZERERERESUmSIjI2Fra6vEhm/zWQfP2qHaefLkYfBMRERERET0mXqX23g5YRgRERERERFRBhg8ExEREREREWWAwTMRERERERFRBj7re56JiIiIiOjDJCUlISEhIaurQZQuQ0PDDB9D9S4YPBMRERER0XsTETx+/Bjh4eFZXRWit9LT00OxYsVgaGj4QfkweCYiIiIiovemDZytra1hamr6TrMVE2W25ORkPHz4EI8ePYKdnd0HHacMnomIiIiI6L0kJSUpgXP+/PmzujpEb2VlZYWHDx8iMTERBgYG/zkfThhGRERERETvRXuPs6mpaRbXhChj2uHaSUlJH5QPg2ciIiIiIvpPOFSbcgK1jlMGz0REREREREQZYPBMRERERERElAEGz0REREREREQZYPBMRERERERElAE+qoqIiOgTdneykyr52H17QZV8iIiI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4Pbt22mm02g02LZtGwYPHozatWtDT08PjRo1woIFC/5THUeOHIlHjx6he/fu0NPTQ69evdC6dWtEREQoaaZPn47k5GR07doVUVFRcHV1xZ49e5AvXz6dvKZPn46hQ4fi+vXrcHFxwY4dO2BoaAgA+Oabb3Dr1i00bNgQpqam6NOnD1q1aqVTztvcv38fnTp1wvPnz2FlZYVatWrh+PHjOveDt2zZEkePHoWvry86d+6MyMhI2NrawtvbGz/88MN/ap93pZGsvus6C0VGRsLCwgIRERHIkydPVleHiIhIdXcnv/+9d2n53H4ME9HbxcbGIiQkROe5xPRpCwwMRJ06dfDixYuP/kgotb3teH2fmDDbDts+ePAgmjdvDhsbG2g0GmzdujXdtP369YNGo1EeQE5ERERERESkpmwbPMfExKBixYpYtGjRW9Nt2bIFx48fh42NTSbVjIiIiIiIPnXTpk1D7ty503w1btw4S+tWvnz5dOumfXRWdnP37t1065w7d+53fpxVVsq29zw3btw4w4PywYMHGDx4MPbs2YOmTZtmUs2IiIiIiOhT169fP7Rv3z7NdSYmJplcG127du1CQkJCmusKFiz4Ucr08vL6oOcs29jY4Ny5c29dn91l2+A5I9qb2UePHo3y5cu/0zZxcXGIi4tT3kdGRn6s6hERERERUQ5maWkJS0vLrK5Gmuzt7bO6Cu8tV65cKFmyZFZX44Nk22HbGZkxYwZy5cqFIUOGvPM2vr6+sLCwUF62trYfsYZERERERET0qciRwfPp06cxf/58rF69GhqN5p23GzduHCIiIpRXyoeOExEREREREaVHtWHbwcHBWL9+PQ4dOoQ7d+7g5cuXsLKyQqVKldCwYUN88cUXMDIyUqWsQ4cOITQ0VOc5aklJSRg5ciTmzZuX7vPSjIyMVKsDERERERERfT4+uOf5zJkzqFevHipVqoTDhw/D3d0dw4YNw5QpU9ClSxeICCZMmAAbGxvMmDFD557j/6pr1644f/48zp07p7xsbGwwevRo7Nmz54PzJyIiIiIiIkrpg3uev/jiC4wePRp//vnnWx+WfezYMcyfPx+zZ8/G+PHjM8w3OjoaN27cUN6HhITg3LlzsLS0hJ2dHfLnz6+T3sDAAIUKFUKZMmX+874QERERERERpeWDg+dr167BwMAgw3TVq1dH9erV051S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2dvbZ3UVPkuqBs/ff/89Jk+eDFdXVxQuXJizbxMRERERfcI45xHlBGodp6oGz0uWLMHq1avRtWtXNbMlIiIiIqJsxMDAAADw8uXLLB/CTJSR+Ph4AIC+vv4H5aNq8BwfH48aNWqomSUREREREWUz+vr6yJs3L0JDQwG8fj4wR51SdpScnIynT5/C1NQUuXJ9WPiravD85ZdfYu3atZg4caKa2RIRERERUTZTqFAhAFACaKLsSk9PD3Z2dh98geeDg+cRI0Yo/09OTsayZcvw999/w9nZWRnOoTVnzpwPLY6IiIiIiLIBjUaDwoULw9raOt2Zn4myA0NDQ+jpffhTmj84eD579qzOexcXFwDAxYsXdZZzGAcRERER0adHX1//g+8lJcoJPjh4DggIUKMeRERERERERNnWh/ddExEREREREX3iGDwTERERERERZYDBMxEREREREVEGGDwTERERERERZYDBMxEREREREVEGPkrw3KFDh4+RLREREREREVGW+OBHVQHA5MmTlf+LCIKCgj44z4MHD2LWrFk4ffo0Hj16hC1btqBVq1YAgISEBHzzzTfYtWsXbt26BQsLC9SrVw/Tp0+HjY3NB5dNRERERERElJIqPc8bN26EiEBE1MgOABATE4OKFSti0aJFqda9fPkSZ86cwcSJE3HmzBls3rwZV69eRYsWLVQrn4iIiIiIiEhLlZ5nR0dHfPfdd8r7K1eufHCejRs3RuPGjdNcZ2FhgX379uksW7hwIapWrYq7d+/Czs4uze3i4uIQFxenvI+MjPzgehIREREREdGnT5We5w0bNui8X7dunRrZvpeIiAhoNBrkzZs33TS+vr6wsLBQXra2tplXQSIiIiIiIsqxVAmeNRqNGtn8Z7GxsRgzZgw6deqEPHnypJtu3LhxiIiIUF737t3LxFoSERERERFRTqXqbNudO3dWM7t3kpCQgPbt20NEsHjx4remNTIyQp48eXReRERERERERBlR5Z5nLTUnDHsX2sD5zp07+OeffxgMExERERER0UehavCcmcO3tYHz9evXERAQgPz582da2URERERERPR5UTV4VlN0dDRu3LihvA8JCcG5c+dgaWmJwoULo23btjhz5gx27tyJpKQkPH78GABgaWkJQ0PDrKo2ERERERERfYKy7bDtU6dOoU6dOsr7ESNGAAC6d++OSZMmYfv27QAAFxcXne0CAgLg5eWlWj2IiIiIiIiIVA2eu3TpolpeXl5ebw3GM/v+aiIiIiIiIvp8qTLbdlxcHACgadOmamRHRERERERElK2o0vNsYWGB6tWro06dOqhTpw6qVasGAwMDNbImIiIiIiIiynKq9DwvWbIE9vb2+OWXX+Dp6Ym8efOifv368PX1xfHjx5GUlKRGMURERERERERZQpXguUePHli9ejVu376NGzduYMGCBbCxscGSJUtQs2ZN5MuXj0O6iYiIiIiIKMdS/VFVxYsXR/HixdGrVy+EhIRg5cqVWLBgAfz9/dUuioiIiIiIiChTqBo83717FwEBAQgMDERgYCCePXuGatWqYdSoUfD09FSzKCIiIiIiIqJMo0rw3KtXLwQGBiIsLAw1a9aEh4cH+vTpAzc3N+TKpXrnNhEREREREVGmUiWyXb16Nezs7DBhwgTUrVsXlSpVgkajUSNrIiIiIiIioiynSvAcHBysDNeePXs24uLiUKtWLXh6esLLywuVK1eGnp4qc5MRERERERERZTpVItoyZcqgX79+WL9+PR4/fowjR46gSZMmOHnyJJo1awZLS0s0a9ZMjaKIiIiIiIiIMt1HuSHZ0dER+fPnR758+ZAvXz6sX78eu3fv/hhFEREREREREX10qgXPoaGhCAwMVIZvX7t2DYaGhqhatSqGDx+OOnXqqFUUERERERERUaZSJXguV64crl27hly5csHNzQ1t27aFl5cXatasCWNjYzWKICIiIiIiIsoyqgTPrVq1Qp06dVCrVi2YmpqqkSURERERERFRtqFK8Ozr66tGNkRERERERETZkmrPj4qJicG3336LChUqIHfu3DA3N4ezszMmT56Mly9fqlUMERERERERUaZTpec5Pj4enp6euHjxIho3bozmzZtDRBAcHIypU6di9+7dOHjwIAwMDNQojoiIiIiIiChTqRI8L168GPfv38e///6LMmXK6Ky7cuUKvLy8sGTJEgwePFiN4oiIiIiIiIgylSrDtjdv3oyJEyemCpwBoGzZspgwYQL+/PNPNYoiIiIiIiIiynSqBM+XL1+Gl5dXuuvr1KmDy5cvq1EUERERERERUaZTJXgODw9H/vz5012fP39+REREqFEUERERERERUaZTJXhOTk6Gvr5++oXo6SEpKUmNooiIiIiIiIgynSoThokI6tati1y50s4uMTFRjWKIiIiIiIiIsoQqwfN3332XYZovvvhCjaKIiIiIiIiIMl2mBc9EREREREREOZUq9zwTERERERERfcpUDZ4rVaqEypUrp3pVqVIFNWvWRPfu3REQEPBOeR08eBDNmzeHjY0NNBoNtm7dqrNeRPDtt9+icOHCMDExQb169XD9+nU1d4eIiIiIiIgIgMrBc6NGjXDr1i2YmZmhTp06qFOnDnLnzo2bN2/Czc0Njx49Qr169bBt27YM84qJiUHFihWxaNGiNNfPnDkTP/30E5YsWYITJ07AzMwMDRs2RGxsrJq7RERERERERKTOPc9az549w8iRIzFx4kSd5T/88APu3LmDvXv34rvvvsOUKVPQsmXLt+bVuHFjNG7cOM11IoJ58+bhm2++UfL59ddfUbBgQWzduhUdO3ZUZ4eIiIiIiIiIoHLP88aNG9GpU6dUyzt27IiNGzcCADp16oSrV69+UDkhISF4/Pgx6tWrpyyzsLCAu7s7jh07lu52cXFxiIyM1HkRERERERERZUTV4NnY2BhHjx5Ntfzo0aMwNjYGACQnJyv//68eP34MAChYsKDO8oIFCyrr0uLr6wsLCwvlZWtr+0H1ICIiIiIios+DqsO2Bw8ejH79+uH06dNwc3MDAAQFBWHFihUYP348AGDPnj1wcXFRs9h3Nm7cOIwYMUJ5HxkZyQCaiIiIiIiIMqRq8PzNN9+gWLFiWLhwIX777TcAQJkyZbB8+XJ07twZANCvXz/079//g8opVKgQAODJkycoXLiwsvzJkydvDcyNjIxgZGT0QWUTERERERHR50fV4BkAfHx84OPjk+56ExOTDy6jWLFiKFSoEPbv368Ey5GRkThx4sQHB+ZEREREREREb1I9eFZLdHQ0bty4obwPCQnBuXPnYGlpCTs7OwwbNgw//PADSpUqhWLFimHixImwsbFBq1atsq7SRERERERE9EnKtsHzqVOnUKdOHeW99l7l7t27Y/Xq1fj6668RExODPn36IDw8HLVq1YK/v/8HT0ZGRERERERE9KZsGzx7eXlBRNJdr9FoMHnyZEyePDkTa0VERERERESfI1UfVUVERERERET0KWLwTERERERERJSBDx62nfK5yRmZM2fOhxZHRERERERElOk+OHg+e/bsO6XTaDQfWhQRERERERFRlvjg4DkgIECNehARERERERFlWx/tnuf79+/j/v37Hyt7IiIiIiIiokyjavCcnJyMyZMnw8LCAvb29rC3t0fevHkxZcoUJCcnq1kUERERERERUaZR9TnPEyZMwMqVKzF9+nTUrFkTAHD48GFMmjQJsbGxmDp1qprFEREREREREWUKVYPnNWvWYMWKFWjRooWyzNnZGUWKFMGAAQM+2+D57mQn1fKy+/aCankREX1KeK6ld6XWsfIpHSf8/KSNxwoRpaTqsO2wsDCULVs21fKyZcsiLCxMzaKIiIiIiIiIMo2qwXPFihWxcOHCVMsXLlyIihUrqlkUERERERERUaZRddj2zJkz0bRpU/z999+oXr06AODYsWO4d+8edu3apWZRRERERERERJlG1Z5nT09PXLt2Da1bt0Z4eDjCw8PRpk0bXL16FR4eHmoWRURERERERJRpVO15BgAbG5vPdmIwIiIiIiIi+jSpHjzHxsbi/PnzCA0NTfVs55SzcBMRERERERHlFKoGz/7+/ujWrRuePXuWap1Go0FSUpKaxRERERERERFlClXveR48eDDatWuHR48eITk5WefFwJmIiIiIiIhyKlWD5ydPnmDEiBEoWLCgmtkSERERERERZSlVg+e2bdsiMDBQzSyJiIiIiIiIspyq9zwvXLgQ7dq1w6FDh+Dk5AQDAwOd9UOGDFGzOCIiIiIiIqJMoWrwvG7dOuzduxfGxsYIDAyERqNR1mk0GgbPRERERERElCOpGjxPmDAB33//PcaOHQs9PVVHhBMRERERERFlGVUj3Pj4eHTo0IGBMxEREREREX1SVI1yu3fvjg0bNqiZJREREREREVGWU3XYdlJSEmbOnIk9e/bA2dk51YRhc+bMUbM4IiIiIiIiokyhavB84cIFVKpUCQBw8eJFnXUpJw8jIiIiIiIiyklUDZ4DAgLUzI6IiIiIiIgoW8ixM3slJSVh4sSJKFasGExMTFCiRAlMmTIFIpLVVSMiIiIiIqJPjKo9z7GxsViwYAECAgIQGhqK5ORknfVnzpxRrawZM2Zg8eLFWLNmDcqXL49Tp06hZ8+esLCw4POkiYiIiIiISFWqBs+9e/fG3r170bZtW1StWvWj3ud89OhRtGzZEk2bNgUAODg4YN26dTh58mS628TFxSEuLk55HxkZ+dHqR0RERERERJ8OVYPnnTt3YteuXahZs6aa2aapRo0aWLZsGa5du4bSpUvj33//xeHDh986o7evry++//77j143IiIiIiIi+rSoGjwXKVIE5ubmamaZrrFjxyIyMhJly5aFvr4+kpKSMHXqVPj4+KS7zbhx4zBixAjlfWRkJGxtbTOjukRERERERJSDqTph2OzZszFmzBjcuXNHzWzTtHHjRvj5+WHt2rU4c+YM1qxZgx9//BFr1qxJdxsjIyPkyZNH50VERERERESUEVV7nl1dXREbG4vixYvD1NQUBgYGOuvDwsJUK2v06NEYO3YsOnbsCABwcnLCnTt34Ovri+7du6tWDhEREREREZGqwXOnTp3w4MEDTJs2DQULFvyoE4a9fPkSenq6Hef6+vqpZvgmIiIiIiIi+lCqBs9Hjx7FsWPHULFiRTWzTVPz5s0xdepU2NnZoXz58jh79izmzJmDXr16ffSyiYiIiIiI6POiavBctmxZvHr1Ss0s07VgwQJMnDgRAwYMQGhoKGxsbNC3b198++23mVI+ERERERERfT5UDZ6nT5+OkSNHYurUqXByckp1z7OaE3SZm5tj3rx5mDdvnmp5vqnK6F9VyWdL5kxAninUahMAOD2rm2p5ZTW12oVtkhrbJG1sl9Q+pXMtpabm54fHClHWq7lAvUfbHhl8RLW8sppa7cI2SU2NNlE1eG7UqBEAoG7dujrLRQQajQZJSUlqFkdERERERESUKVQNngMCAtTMjoiIiIiIiChbUDV49vT0VDM7IiIiIiIiomxBL+Mkb3f37t33Sv/gwYMPLZKIiIiIiIgoU31w8Ozm5oa+ffsiKCgo3TQRERFYvnw5KlSogE2bNn1okURERERERESZ6oOHbV++fBlTp05F/fr1YWxsjCpVqsDGxgbGxsZ48eIFLl++jEuXLqFy5cqYOXMmmjRpoka9iYiIiIiIiDLNB/c858+fH3PmzMGjR4+wcOFClCpVCs+ePcP169cBAD4+Pjh9+jSOHTvGwJmIiIiIiIhyJNUmDDMxMUHbtm3Rtm1btbIkIiIiIiIiyhY+uOeZiIiIiIiI6FPH4JmIiIiIiIgoAwyeiYiIiIiIiDLA4JmIiIiIiIgoAwyeiYiIiIiIiDLwwbNtb9++/Z3TtmjR4kOLIyIiIiIiIsp0Hxw8t2rV6p3SaTQaJCUlfWhxRERERERERJnug4Pn5ORkNepBRERERERElG3xnmciIiIiIiKiDHxwz/ObYmJicODAAdy9exfx8fE664YMGaJ2cUREREREREQfnarB89mzZ9GkSRO8fPkSMTExsLS0xLNnz2Bqagpra2sGz0RERERERJQjqTpse/jw4WjevDlevHgBExMTHD9+HHfu3EGVKlXw448/qlkUERERERERUaZRNXg+d+4cRo4cCT09Pejr6yMuLg62traYOXMmxo8fr2ZRRERERERERJlG1eDZwMAAenqvs7S2tsbdu3cBABYWFrh3756aRRERERERERFlGlXvea5UqRKCgoJQqlQpeHp64ttvv8WzZ8/w22+/oUKFCmoWRURERERERJRpVO15njZtGgoXLgwAmDp1KvLly4f+/fvj6dOnWLp0qZpFEREREREREWUaVXueXV1dlf9bW1vD399fzeyJiIiIiIiIsoSqPc/e3t4IDw9PtTwyMhLe3t5qFkVERERERESUaVQNngMDAxEfH59qeWxsLA4dOqRmUQCABw8eoEuXLsifPz9MTEzg5OSEU6dOqV4OERERERERfd5UGbZ9/vx55f+XL1/G48ePlfdJSUnw9/dHkSJF1ChK8eLFC9SsWRN16tTB7t27YWVlhevXryNfvnyqlkNERERERESkSvDs4uICjUYDjUaT5vBsExMTLFiwQI2iFDNmzICtrS1WrVqlLCtWrNhbt4mLi0NcXJzyPjIyUtU6ERERERER0adJlWHbISEhuHnzJkQEJ0+eREhIiPJ68OABIiMj0atXLzWKUmzfvh2urq5o164drK2tUalSJSxfvvyt2/j6+sLCwkJ52draqlonIiIiIiIi+jSp0vNsb28PAEhOTlYju3dy69YtLF68GCNGjMD48eMRFBSEIUOGwNDQEN27d09zm3HjxmHEiBHK+8jISAbQRERERERElCFVH1UFADdv3sS8efMQHBwMAHB0dMTQoUNRokQJVctJTk6Gq6srpk2bBgCoVKkSLl68iCVLlqQbPBsZGcHIyEjVehAREREREdGnT9XZtvfs2QNHR0ecPHkSzs7OcHZ2xokTJ1C+fHns27dPzaJQuHBhODo66iwrV64c7t69q2o5RERERERERKr2PI8dOxbDhw/H9OnTUy0fM2YM6tevr1pZNWvWxNWrV3WWXbt2TRlCTkRERERERKQWVXueg4OD0bt371TLe/XqhcuXL6tZFIYPH47jx49j2rRpuHHjBtauXYtly5Zh4MCBqpZDREREREREpGrwbGVlhXPnzqVafu7cOVhbW6tZFNzc3LBlyxasW7cOFSpUwJQpUzBv3jz4+PioWg4RERERERGRqsO2v/rqK/Tp0we3bt1CjRo1AABHjhzBjBkzdGa5VkuzZs3QrFkz1fMlIiIiIiIiSknV4HnixIkwNzfH7NmzMW7cOACAjY0NJk2ahCFDhqhZFBEREREREVGmUTV41mg0GD58OIYPH46oqCgAgLm5uZpFEBEREREREWU6Ve959vb2Rnh4OIDXQbM2cI6MjIS3t7eaRRERERERERFlGlWD58DAQMTHx6daHhsbi0OHDqlZFBEREREREVGmUWXY9vnz55X/X758GY8fP1beJyUlwd/fH0WKFFGjKCIiIiIiIqJMp0rw7OLiAo1GA41Gk+bwbBMTEyxYsECNooiIiIiIiIgynSrBc0hICEQExYsXx8mTJ2FlZaWsMzQ0hLW1NfT19dUoioiIiIiIiCjTqRI829vbAwCSk5PVyI6IiIiIiIgoW1F1wjAiIiIiIiKiTxGDZyIiIiIiIqIMMHgmIiIiIiIiygCDZyIiIiIiIqIMqDJhGABs2LAB27dvR3x8POrWrYt+/fqplTURERERERFRllIleF68eDEGDhyIUqVKwcTEBJs3b8bNmzcxa9YsNbInIiIiIiIiylKqDNteuHAhvvvuO1y9ehXnzp3DmjVr8PPPP6uRNREREREREVGWUyV4vnXrFrp3766879y5MxITE/Ho0SM1siciIiIiIiLKUqoEz3FxcTAzM/tfpnp6MDQ0xKtXr9TInoiIiIiIiChLqTZh2MSJE2Fqaqq8j4+Px9SpU2FhYaEsmzNnjlrFEREREREREWUaVYLn2rVr4+rVqzrLatSogVu3binvNRqNGkURERERERERZTpVgufAwEA1siEiIiIiIiLKllS557l48eJ4/vy5GlkRERERERERZTuqBM+3b99GUlKSGlkRERERERERZTuqBM9EREREREREnzLVZtves2ePzszaaWnRooVaxRERERERERFlGtWC5+7du791vUaj4dBuIiIiIiIiypFUG7b9+PFjJCcnp/ti4ExEREREREQ5lSrBc3Z4hvP06dOh0WgwbNiwrK4KERERERERfWJUCZ5FJMM0Fy9eVKOoNAUFBWHp0qVwdnb+aGUQERERERHR50uV4Ll79+4wMTFJtTwqKgrLli1D1apVUbFiRTWKSiU6Oho+Pj5Yvnw58uXL91HKICIiIiIios+bKsHzqlWrYG5urrw/ePAgunfvjsKFC+PHH3+Et7c3jh8/rkZRqQwcOBBNmzZFvXr1MkwbFxeHyMhInRcRERERERFRRlSbbfvx48dYvXo1Vq5cicjISLRv3x5xcXHYunUrHB0d1SpGx/r163HmzBkEBQW9U3pfX198//33H6UuRERERERE9OlSpee5efPmKFOmDM6fP4958+bh4cOHWLBggRpZp+vevXsYOnQo/Pz8YGxs/E7bjBs3DhEREcrr3r17H7WORERERERE9GlQped59+7dGDJkCPr3749SpUqpkWWGTp8+jdDQUFSuXFlZlpSUhIMHD2LhwoWIi4uDvr6+zjZGRkYwMjLKlPoRERERERHRp0OVnufDhw8jKioKVapUgbu7OxYuXIhnz56pkXW66tatiwsXLuDcuXPKy9XVFT4+Pjh37lyqwJmIiIiIiIjov1IleK5WrRqWL1+OR48eoW/fvli/fj1sbGyQnJyMffv2ISoqSo1idJibm6NChQo6LzMzM+TPnx8VKlRQvTwiIiIiIiL6fKkSPGuZmZmhV69eOHz4MC5cuICRI0di+vTpsLa2RosWLdQsioiIiIiIiCjTqBo8p1SmTBnMnDkT9+/fx7p16z5WMToCAwMxb968TCmLiIiIiIiIPh8fLXjW0tfXR6tWrbB9+/aPXRQRERERERHRR/HRg2ciIiIiIiKinI7BMxEREREREVEGGDwTERERERERZYDBMxEREREREVEGGDwTERERERERZYDBMxEREREREVEGGDwTERERERERZYDBMxEREREREVEGGDwTERERERERZYDBMxEREREREVEGGDwTERERERERZYDBMxEREREREVEGGDwTERERERERZYDBMxEREREREVEGGDwTERERERERZYDBMxEREREREVEGGDwTERERERERZYDBMxEREREREVEGGDwTERERERERZYDBMxEREREREVEGGDwTERERERERZYDBMxEREREREVEGGDwTERERERERZYDBMxEREREREVEGGDwTERERERERZYDBMxEREREREVEGcnTw7OvrCzc3N5ibm8Pa2hqtWrXC1atXs7paRERERERE9InJ0cHzgQMHMHDgQBw/fhz79u1DQkICGjRogJiYmKyuGhEREREREX1CcmV1BT6Ev7+/zvvVq1fD2toap0+fRu3atVOlj4uLQ1xcnPI+MjLyo9eRiIiIiIiIcr4c3fP8poiICACApaVlmut9fX1hYWGhvGxtbTOzekRERERERJRDfTLBc3JyMoYNG4aaNWuiQoUKaaYZN24cIiIilNe9e/cyuZZERERERESUE+XoYdspDRw4EBcvXsThw4fTTWNkZAQjI6NMrBURERERERF9Cj6J4HnQoEHYuXMnDh48iKJFi2Z1dYiIiIiIiOgTk6ODZxHB4MGDsWXLFgQGBqJYsWJZXSUiIiIiIiL6BOXo4HngwIFYu3Yttm3bBnNzczx+/BgAYGFhARMTkyyuHREREREREX0qcvSEYYsXL0ZERAS8vLxQuHBh5bVhw4asrhoRERERERF9QnJ0z7OIZHUViIiIiIiI6DOQo3ueiYiIiIiIiDIDg2ciIiIiIiKiDDB4JiIiIiIiIsoAg2ciIiIiIiKiDDB4JiIiIiIiIsoAg2ciIiIiIiKiDDB4JiIiIiIiIsoAg2ciIiIiIiKiDDB4JiIiIiIiIsoAg2ciIiIiIiKiDDB4JiIiIiIiIsoAg2ciIiIiIiKiDDB4JiIiIiIiIsoAg2ciIiIiIiKiDDB4JiIiIiIiIsoAg2ciIiIiIiKiDDB4JiIiIiIiIsoAg2ciIiIiIiKiDDB4JiIiIiIiIsoAg2ciIiIiIiKiDDB4JiIiIiIiIsoAg2ciIiIiIiKiDDB4JiIiIiIiIsoAg2ciIiIiIiKiDDB4JiIiIiIiIsoAg2ciIiIiIiKiDOT44HnRokVwcHCAsbEx3N3dcfLkyayuEhEREREREX1icnTwvGHDBowYMQLfffcdzpw5g4oVK6Jhw4YIDQ3N6qoRERERERHRJyRHB89z5szBV199hZ49e8LR0RFLliyBqakpfvnll6yuGhEREREREX1CcmV1Bf6r+Ph4nD59GuPGjVOW6enpoV69ejh27Fia28TFxSEuLk55HxERAQCIjIxMM31S3CtV6hplkKRKPkD6dc0sarUJkPX7oia12oVtkhrbJG1sl9R4rk2bWu3CNkktq9tETVGxn87nR01qtcun1CZqSXyVqFpen1L7qtUubJPU0msT7XIRyTAPjbxLqmzo4cOHKFKkCI4ePYrq1asry7/++mscOHAAJ06cSLXNpEmT8P3332dmNYmIiIiIiCibu3fvHooWLfrWNDm25/m/GDduHEaMGKG8T05ORlhYGPLnzw+NRpOFNXt9xcPW1hb37t1Dnjx5srQu2QXbJDW2SdrYLqmxTVJjm6SN7ZIa2yQ1tkna2C6psU1SY5ukLbu0i4ggKioKNjY2GabNscFzgQIFoK+vjydPnugsf/LkCQoVKpTmNkZGRjAyMtJZljdv3o9Vxf8kT548/FC9gW2SGtskbWyX1NgmqbFN0sZ2SY1tkhrbJG1sl9TYJqmxTdKWHdrFwsLindLl2AnDDA0NUaVKFezfv19ZlpycjP379+sM4yYiIiIiIiL6UDm25xkARowYge7du8PV1RVVq1bFvHnzEBMTg549e2Z11YiIiIiIiOgTkqOD5w4dOuDp06f49ttv8fjxY7i4uMDf3x8FCxbM6qq9NyMjI3z33XephpV/ztgmqbFN0sZ2SY1tkhrbJG1sl9TYJqmxTdLGdkmNbZIa2yRtObFdcuxs20RERERERESZJcfe80xERERERESUWRg8ExEREREREWWAwTMRERERERFRBhg8ExERfeKSk5OzugpEREQ5HoNnomxCO3dfcHBwFteEchoGRqnt2rUL//77b1ZXI0uJiHJs6Om9/rpPSkrKyiplGydOnMDjx4+zuhpEORa/d1KLiYkBwLZJ6eTJk7h37x6A//3OzekYPFOWSEhIQL169bBlyxYkJCRkdXWy3KtXr6DRaHDnzh3Ur18f06ZN44/c/xcTE4OffvoJT548yeqqZCtHjx5F9erVcffuXSUw+twdP34cnTp1gqmpKbp06YLw8PCsrlKW0mg00NPTQ0REBH744Qd4eHggMDAwq6uVJd78MTtr1iz07dsXO3bsAPDp/Kgj9SUnJ/P7+A3Tp0/HkCFDcPHiRQC8KBcWFobx48ejd+/eAMDv5P93/fp1zJs3D19++SWeP38OjUbzSZxr+df9iEQEf/31l3J1+3O/EvXPP/9g8eLFCAsLg4GBAdq1a4dly5bh+++/z+qqZRkRQbNmzTBlyhS8fPkS9vb22L59OzZv3oxJkyZ9tsdMeHg4bt68CQCIjIzE/v37MWjQIJw9exbA5/lZiouLw/jx45XeVFdXV5QtWxYjRozA33//DeDzbBcAWLp0KaysrNCgQQPo6+tjz549CAsLg6enZ1ZXLUtt2bIF1apVg6WlJTZv3oyOHTvCw8Mjq6uV6UQEenp6CA8Px4sXLwAAK1euRP369dGnTx/cvn0bGo0mi2uZde7du4dVq1ZldTWyLT09Pejr6wMAzp8//9meZ4H/fce0bNkSpqam6NixI8LDw5X2+VxZWlpi2LBhuHDhAiZMmKBc7P8UAsUPUapUKaxevRoigqFDhyIyMvLTONcKfTSBgYFib28vU6ZMERGRxMTELK5R1khOThYRkREjRkiJEiUkKChIWefv7y9WVlaycePGrKpeltEeD126dJG6devK1atXlXVbtmwRJycnWbhwYVZVL8vEx8dLkyZNpEqVKsqyp0+fSt++fcXd3f2z/RyFh4dLsWLFpFu3bsqyhw8fypgxY6R06dISFxeXhbXLfImJiZKQkCAiIgMGDBBTU1MJCQnJ2kplI7t27RKNRiOdO3eW58+f66zTnpM/RSn3LSkpSfn/9evXxcjISDZs2KCT3tvbW3x8fOTmzZuZVsfsIOV5dMOGDaLRaOTWrVtZWKOs9+rVqzSXBwUFyRdffCFWVlZSq1YtCQ4OzuSaZY2oqCgR+d/nKK3zRpUqVaRv375y//79dNN8StI7v2i/i/7++2+pW7euDB48ONPrlhXi4uLkt99+E5HXbZOYmKjTLtr2Onv2rFSsWFFGjhyZJfVUG3ueVXLmzBmMHDkSo0ePxs6dOwEAFSpUQP369XHw4EEA+GyvzMn/X3nr378/EhMTde5DbNiwITp37oyff/4Zp0+fzqoqZipte2ivvvXp0wdXr17F+fPnlTStWrVCkyZNsHr1aty6dStL6plV9PT00LVrVwQHByvDbgsUKIAffvgBDx8+xHfffYeXL19mbSUzUWJiIkQEFhYWGDJkCHbt2qWsK1y4MCZNmoTw8HD4+voiKioqC2v68SUnJyMxMRHA6/Nprly5AABDhgxBfHw8rl+/rqSNiorCjBkzlF75T11SUpJOj1jp0qVRq1YtFChQAJaWljppP4kr/+nQ7tulS5eUoZMigpIlS6J48eI4duwYoqOjlfRjx47FgwcPsGLFiiypb2ZKTEzEsmXL0K5dO4wYMQKHDh1CUlISWrVqBWtra51zy+ciNDQUEydORI0aNdC7d29MmTJF5174W7duYfDgwTAwMMCOHTswd+5c5MuXLwtr/PG9evUKI0aMQM+ePXWWpzxvaM/DU6ZMwdWrV7Fw4UIAn25Pa2hoKGxsbLB69WoAr7+LUg7N1v6+r1u3LoYMGYKff/4Zx48fz4qqflRv/n0vXLiAbt26ITAwEBqNBvr6+tDT00s1OsPFxQUTJkzAsmXLPol2YfD8AZKSkjBjxgw4ODigdu3auH79Os6cOYMWLVpg0aJFyJ8/P6pVq4bbt2/j1KlTAD6fYZUpf8jp6enp/Hg5cOAAQkNDlbTdu3dHrly5sGzZsqyqbqZISkqCiChfQNoTr4eHBywtLXH06FGd4KdNmzbQaDRYuXJlltQ3s2lPyvr6+vDw8EDevHnx+++/A3h9j3yBAgUwceJEbNq0CQcOHMjKqmaqXLlyKceMt7c3YmNjlQt08fHxMDY2xogRI7Bz506cPHkyK6v6Ucn/D73VBsyHDh1C586dERoaijJlysDW1hY7duzAunXr0KBBA9jb22PZsmWIi4vL4pp/PG9eTNDT08PTp09x+vRplChRAvXq1cPmzZsBANeuXcPQoUNhZWWFa9euZWW1VSEiyjkj5Q+6R48ewcnJCU5OTli1ahWioqKUz0/nzp2xZ88e3L17V0lfs2ZNeHh4YP369Zm7A5nozp076Ny5MwwNDfHTTz/B3t4e+/fvR5s2bbB582YYGhqiUaNG+PXXXz+rOUh+++03VKtWDQcPHkTnzp1RsGBBzJw5E7Vr18b+/fsBAOvWrcPTp0+xdu1auLu7o3LlyihYsGAW1/zjMjExQa5cufD48WMEBwdDT08PL168wNatW5XOD+15uE6dOmjUqBGWLFkC4NO41zetCwAWFhaoVq0a1q5dC+D1fh49ehQrVqzAkydPlHOMiKBFixZwcnLCypUrERYWlql1/9hS7icAlClTBp6enspFhY0bN6Jhw4bo1q0b/vnnH50LLu3atUPBggWxefPmnH+hP/M7u3O2hIQE+fnnn2XkyJGSnJwsZmZm0qxZM3nx4oWSpkWLFlK6dGm5du2aBAcHS82aNWXMmDEi8vkN3Y6Li9MZ5vLzzz9L2bJl5eDBgzppZs6cKYULF5b4+PisqGamunHjhhw6dEhiYmKUZePHjxc3Nzc5e/assiw6OlrGjBkj5cqVy4JaZo3g4GAZO3asLFiwQJo0aSK1atUSkf99bl6+fClVq1aVYcOGpTvE7lNz7do1adOmjRQvXlyGDx8uRkZG0r17dxH531Cx+/fvS5UqVeS7777LuoqqLK3hf//++698+eWXYmZmJsbGxqLRaGTVqlUiIjJ//nzRaDRSokQJGTNmjJw7dy6Ta5x14uLiZMGCBVK+fHnRaDTSqlUrSUxMlEOHDknhwoWlQIECkj9/fmnZsqWsW7cuRw/xTzkkUCT1d2pYWJh07NhRNBqN1K5dW3r37q2su3fvnpibmyvDDLUCAgLE1tZWtm3b9vEqnsnOnDkjLVu2lJ07d8qOHTukYMGCOueHf//9V2rXri3u7u4iInLo0CHR09OTf//9N4tq/PFozyV79+6V3377TeLi4uTatWtSpkyZVOfMM2fOiJubm1SoUEFiYmJk7969YmxsLOPGjZORI0fKpEmTZNy4cXL06NFUx2JOdvfuXUlKSlL2ae/evVKjRg2ZMWOGrF27VkxNTaVUqVJStGhRWb16tc62wcHBYmFhIWvXrhWRT2PodkREhFy+fFln2ebNm0VfX1/u3bsn7dq1kwIFCkixYsXE2dlZ9u3bJyIisbGxIiKydOlSKV26tBw7dizT6/6xhIWFyYIFC5R91Vq4cKFYWFjIiRMnpHbt2jJ69Ghp1KiRWFhYKPuv/c6ZOHGiVK5cWa5fv57p9VdTzr9ElEkOHDiAxo0bw9jYGHPnzoWDgwM0Gg06duwIEcGzZ8+UntZu3brh9u3bePHiBezt7eHq6op//vkHIvLZDN3euHEjPDw84O3tjbFjxyIkJAQA0L59e8TExCAoKEhpL0NDQ7i5ucHc3By7d+/Oymr/Z/Hx8cr/0xtdEBgYCCcnJ7i4uKBfv35o1qwZAgICALzuEXnw4IEyIRYAmJmZwcXFBXp6ejpDunOyt81a+tdff6FatWq4dOkSnj59iqCgIBw5cgQhISHQ19dHUlISTExMULt2bVy6dAm3b9/O3Mp/JElJSem2SWxsLH744Qc8ffoUa9asgZubG4oVK4Y//vgDUVFRyJUrF0QERYoUQalSpXDt2jU8e/Ysk/dAPSmPjzeHFs+fPx8uLi54/Pgx9u7di61bt6JChQpo2bIlAKBHjx4AgEmTJmH69OmoWLGiTu9kTiYiSg9zSuHh4WjevDmMjY2xaNEiDBw4EG5ubihRogT09fVhZ2eH2rVro0CBAnj69Cm2bt2Kjh07wtDQMAv2Qh16enpISkrC8uXL0bx5cwwZMgSLFy9WHoVibm6OJk2aQF9fH6NGjcKff/6JQYMG4dmzZyhatCicnZ2xe/dunR4hOzs7ODk54ejRo1m1W6oIDQ3FrFmzYGdnBy8vL0RFRaF06dJwcXFB3bp1ceHCBQCvh9w6OzujdOnSePjwIZ49e4ZatWrBwcEBGzduzOK9UJ9Go8GDBw/QvXt3hIaGwtDQEL///juio6MxYsQIAP/73nZ2doavry8uXbqE33//HfXr18c333yDY8eO4eXLl7h58ya2bNmCkSNHYt++fVm5W6r55ptvUKtWLejp6UFPTw8hISHw9PSEra0t/P39sXPnTgQEBODff/9FrVq1sHLlSp3Pip2dHerVq6f0yub0c25UVBQaNGigDEWPiorC3bt3UbNmTRQtWhRdu3ZF6dKl8ejRI2zfvh22trYYP348AMDAwADA/37TPXz4MMv2Q22RkZFYsGABTp48iZs3b2LgwIG4fPkyGjZsCGNjY7Ru3RrDhw/HzJkzsXr1alSvXh1TpkwB8L9h7Z07d8aFCxd0fjPnSFkYuGd7Z86ckS5duoiZmZloNBopVqxYqitR+/fvl6JFi8qmTZuUZTNmzJAiRYrI7du3RUTEz89PypUrJ7t37xaRtCcZyAl8fX1l2bJlIiKpJgVIadWqVVKsWDEZO3asLF26VOzs7MTT01Nu3LghIiKtWrWSFi1ayJ07d5RtLl++LA0bNpQff/zx4++IiiIjI8XS0jLVldg3PX/+XBo3bix9+/aVhw8fypEjR6RZs2ZSsmRJCQsLExGRWrVqSY8ePSQ0NFTZbu/evVKrVi3ZtWvXR92PrPDmKINq1arp9BL5+/uLtbW1fPPNNzrp9+7dK0WLFpXz589nXmUzQVhYmOzZs0cePnyoLLtz545oNBrZv3+/suzIkSNiYWGhfBa1V3QXLlwopUuX1hnRkJMdOnRI5+r0ixcvlAlsRER69eol7dq1E5H/9T7WqFFD2rVrJ+Hh4anyS/m5yo7S6615c3nKERfPnz+XX375RektfPjwodja2kpgYKCIvG6Xn3/+WfLly6ccFzm9V2jnzp1SsmRJKVeunIwbN0769u0rpqam4ujoKJcuXRIRkZCQEMmdO7f4+/vLgQMHxNHRUVq2bCkvX76UP/74QwoXLiwnT55U8nz16pW0bt1axowZk+NGhyUlJcn8+fPF2dlZNBqNaDQa6dixY6p0s2fPljJlysjdu3eVZbVq1ZJOnTop59Zvv/1WSpQoIdHR0am2z0ntEhsbK+vWrZPDhw8rywYPHiyurq4i8vq7pGPHjuLs7Jzm9i9fvhQXFxf54osvdPZb+xm6c+eOWFtbyx9//PER9+LjefO32+3bt8XAwEA6dOggefPmlSpVqkh8fLz89NNPkjdvXp3Jr06fPi3e3t4yatQoZVlCQoJMmzZNatWqlSNHtSQnJyttov17jxgxQpydnaVKlSqi0WhkypQpkpCQIBMmTBCNRiM7d+5Utj927Jjo6ekpIwe1eTg5OcmkSZNEJHWbZ3dJSUk6x772e6NGjRpiamoqpqamUq1aNbly5YpER0dLjx49xMHBQV6+fKlss2XLFjEyMlImkxN5/dkrUKCAbN++XSffnIY9z+n47bff0KBBA8TExMDf3x9z5sxBcnIy7OzsAPzvKqW3tzcsLCxw+vRp7NmzB507d8bYsWPRp08fFCpUCABQpUoV2Nvb488//wTwupfy33//xZgxY9C9e/cccwXm4sWLmDt3LhITE5X76548eaJzT2F8fDwmT56M9u3bw9fXF3369MG2bdsQERGB2bNnA3h95en8+fO4dOmSsl3p0qURFhaG3LlzZ/p+fQhzc3O4u7tj06ZNyrKDBw9ixYoVuH//vrLs/v372Lt3L7788ksULlwYNWrUwKxZs5CYmIjFixcDeH2P88mTJ3XuR3R2dsaNGzdga2ubeTv1EZ04cQJt27ZFhQoV0K9fP+zbtw/JycmIjY1FREQEXF1dlbReXl7o3r07fvvtNwD/u8fK09MTjx8/znH35kk6V+Nv3LiB5s2bo0iRIvjmm29QvXp1/Pbbb4iPj8e9e/dQvHhxmJubK+krVqyIJk2aKPfCa6/oenh46NzLmV2JCB49eoQePXpg1KhROvc+XblyBT169ECePHnQt29fNG3aVDnn5M2bF7lz54aI4MWLF9i/fz+++OILAP87Hw8cOBB79+5VJpo7d+4c+vfvD0tLSyxevDjN3tvsQqPR4OXLl/j99991nk+t0Wjw9OlTfPfdd6hYsSJ69uyp3F9oaWmJnj17wtnZGQCwYcMGWFhYoHbt2gBeHxtVq1ZFnjx5lM9Rdn4ea3qfEa1Hjx5h0qRJ+OKLL3Du3DlMmzYNS5YsweHDhxEXF4c+ffrgypUrcHBwQKNGjTB16lTUrl0bv/32G0JDQ+Hp6Ql3d3fExcXh5MmTyvFgbGyM5ORkJCQkQF9fP8f0nMXFxWHq1KmYPXs2fHx88ODBA7Ro0QJ58uRRjiHtPrq6usLCwgIrV67EqlWrULJkSVy/fh09e/ZUest8fHwQEhKizNHy7NkzrF+/Hu7u7kovXE5w5coV+Pr6ws/PDwDw77//ws/PDzNnzgTwuncwKioKRkZGuHPnDgDdY8/AwADVq1fHhQsXlPPr48ePoa+vj8jISKxfvx4lSpRAzZo1M3nP/jsRUT77b96XPHLkSCQmJuL06dNYvXo1jh49CgMDA3h4eMDe3l7nnFG+fHmUL18eJ06cUM7duXLlgr6+PgoUKKA8Ci4nSE5ORnJyMjQajdIm+vr6uHHjBgIDA3HhwgUULFgQ9+/fxzfffINcuXKhQYMG0Gg0KFy4sJKPi4sLHB0d8euvvyp5iAg8PDyU37k5bZLGlI9n07bRX3/9BT09PeTLlw8LFizAsWPHUKZMGZiZmaFp06a4f/++zvd57dq1kS9fPvzxxx/KsvDwcLi7uyuPIs1p7aLIurg9e9JeBYmOjta5wn/v3j0xMDDQuSdK22v83XffiUajkQIFCkjv3r3lzJkzOnkmJCTI999/L+XKlZMffvhBXF1dRU9PTypUqCBr1qzJhL3675KSkpQ2OXXqlOTKlUtOnz4t27ZtE0dHRylQoIB06NBBjh8/LiIiFy9eFGdnZ+XeF5HXV5p+/PFHyZ8/v4i8buNSpUrJt99+q9PGNWrUkJkzZyppsqs3e923bdsmJiYmEhwcLC1atBBra2spXbq0ODg4yNGjR0VEZOXKlVK5cmWde5pfvXolgwcPFicnJxERefz4sTg4OMhPP/2kcxXUwcFB5wp6dqK9vydlfdO7wnrgwAFxcXGRnj17yo4dO6RHjx5Sq1Yt8fPzk/DwcKlZs6ZMnDhRRP7399+5c6doNBo5ceKEsvz58+dSo0YNnccjZCdXr17VuQKdmJj41joOHTpUWrduLdeuXROR1/fuenh4yO+//y5XrlwRNzc3+fnnn3W2mTFjhmg0Grl3756y7PDhw1KnTh2l9y070rbDpk2bRKPRSKFChXRG8wwePFi6desmR48elYSEBFm4cKG4ubkpjxfS9pD9/vvvUqRIEYmOjk51vBkZGYm3t7eULFlS9PX1pXHjxrJjx45M2sOMpff5CA0NFVdXV9FoNLJgwQIReX38HD16VCpXrize3t4yf/58mThxopiZmcmaNWuUngFtb0+VKlVk8uTJIvK/z+bz58+lZ8+eyvwB2a0HJGWvT0ZmzZolBQsWVEadpOwZ2blzp+jr68usWbNERGTr1q2ip6cnDx48EJHXvfIVK1aULl26iKWlpXTv3l2nF3b06NE6j4HLKd7sJfb19ZUaNWooo1W0v1OeP38uX375pWg0Gqlatar89NNPaeZXq1YtqVOnjvTq1Uvy5s0rFhYW0r59e7ly5crH3RGVDRo0SOrWrSthYWEydOhQadq0qXI+Fnl9DjU1NZWtW7eKSOqe9datW0vlypUlLi5OoqKiZOzYsVK3bl2xtLSUUqVKyR9//CHJycnZ7vsnpfTqtn37dtm5c6fy2bh27Zp88803YmdnpzMaMjExUXr37i2NGzfWedzdb7/9JlWqVJHNmzcry1atWqXMz5LdzjEppVW3GzduyPz582Xz5s3Kfd9Xr16VBg0aSL9+/XRGc4WFhYmTk5OMGDFCRP7Xxr6+vmJnZ6czoq5v377y/fffZ+v2EJE0f6OcOHFCOnToIB4eHjJ27FhlFFhkZKR4eHjI8OHDdUYZ3L9/XwoVKiTz588Xkf+1y+DBg8XNzU1J9+LFC3F3d5cjR4587N36qD7rnmdJ4+qy9iqImZkZjI2NlXvmihYtCk9PT+Xqfcq0HTt2hJWVFSZPnowVK1agUqVKSE5OVrbNlSsXypcvj7CwMCxatAgNGjTA/fv3lSnes6OUVyi1+1mlShU4ODhg1apV+OeffzB06FCsXLkSt2/fRr9+/QAApqamSEpKQlhYmNK+BgYGqFixIgwMDHD27FloNBrUr18f+/btw40bNwC8vpfCzs4OefPmBZA9r0ZJitmg9fT0EB8fDxFBw4YNkTt3bgwZMgTly5fHvXv3sGvXLpQuXRpjxowBAJQtWxYvX77E1atXlfyMjY1RtGhRmJqaIiwsDAULFkTp0qXxxx9/KPfvBQUFwcnJCVZWVpm/w2+xfft2uLu7K/eZprxqq6enh5cvX+o8DiYuLg6//fYbqlSpgl9++QXNmjXDyJEjERoaih9//BEWFhYoVqwYLl++jNDQUOXvr70vUXvlUqPRKMsqVaqkLMsObt26hWrVqsHNzQ3Hjh0D8Lo99PX1odFocP36dfz666+4deuW8vm6cOECgoKCMGXKFJQqVQpBQUE4ePAgDh8+jLNnz6JkyZIoWrQo9u7dq3P1/9y5cwCgMxP7w4cPER4eDkdHx2zTcxYfH489e/Yox4L2bxUTE4MmTZrg2bNnCAgIUHrHGjVqhBkzZqB69ep4+PAhrly5grNnz2LNmjUA/ndFf8OGDWjevDnMzMygp6eH6OhoZaRHu3bt8PTpU4wbNw7x8fHYtWsXmjVrlgV7nzbtZ0XbJtp9Dw8PR2JiIipXrqzcd6qvrw9jY2P07dsX+/fvx5AhQzB58mRUrVoVv/76q9KrYWhoiKNHj+Lhw4do3bo1AMDIyAjA695pDw8PHDlyBA8ePMg2s+Fqj1Ftr09SUhIWLVqETZs2peod16a9du0a8uXLBycnJ2UElFbTpk1RpEgRHD58GFFRUfDw8ECRIkWU3qDChQtj48aNKFiwIF68eIH169cr5+OkpCTcv38/Wx0n7/oZNjMzA/C/46h58+aIjY1VHgejHbFjaWkJd3d3lChRAj/99BMGDx6s9EamLMvHxweBgYF4/PgxfvvtN4SHh2PDhg0oU6aMmrv30WhHoVStWhXJycmYMWMGTpw4gUGDBkFfX19ppx49ekBPTw8bNmxAfHy8ciyJCO7fv4/AwEA0a9YMhoaGyJ07N7y9vdGgQQMEBATg2rVraNu2LTQaTbb5/kkp5Wcr5ftly5Yhf/78GDBgACZMmAAPDw+cP38epUqVwldffYUHDx5g7969AF63o76+PqpXr47nz5/rPOHC3d0dVlZWyj3OwOtReLa2toiPj8825xgtSTH3Rcq6RUVFoUuXLnBycsIff/yBgQMHok2bNggODkbp0qWV0QdBQUHKNnnz5kX79u2xbt06AP9r4zZt2uDevXvYs2ePkvb69eswMjJSnjiTnYiI8lnR/kZ5+vQpAOCff/5B+/btkStXLrRr1w6bN29Gq1atcPPmTZibm6NixYq4cOECgoODlfwKFiyIVq1apXo6zBdffIFTp04p31V58uRBdHR0tjtG3ltmRurZxdt6x95m3bp1kjt3bp3x+1o1a9aU3r17y7Nnz0Tkf1ddtP+Gh4enuV12d/DgQZk1a5YEBQWJiMiPP/4oGo1Gme1X5PX9ZXp6ekrvTtOmTaVjx47y6NEjJc3cuXOlTJkyytUrbS9kyh66Tp06SUhISKbs14dYu3at1KtXT9q3by+nT58WEZGvv/5aNBqNzr3vp06dEj09PaVX3tPTUzp27Kjc4ywiUrt2benWrZtytXLPnj2yYsUKpdcoNDRUJkyYkFm79k6uXr0qzs7O0q9fP2VftJ+nbdu2Sc2aNaVkyZLSqlUrWbx4sYi8nrnSwcFBAgIClFmB8+TJIy1atFCu/K9du1ZcXFxk+PDh8urVK4mOjpbhw4dL5cqVRaPRKGXExsaKo6OjTq9rdjB//nxxd3fXuWdZROT8+fNSs2ZNyZMnjzKL64ABA0RE5OzZs2JgYCDDhg0TW1tbsba2lq5du0pgYKByVXfDhg1SpkwZadGihRw9elSWLl0q3bp1kz59+kinTp2Uci5evCiDBg3KNvcmxsXFiYGBgWg0Ghk3bpxOz8W4ceNk1KhR8uWXX0rVqlUlIiJCWff06VNp06aNFCpUSBo1aiSDBg2S3LlzK3/vBw8eiKOjo/z1119y/PhxadWqlWg0Gunfv7+IZO97M5OTk2Xr1q1iZWUlLVq00Fn38uVLMTc3l0mTJknx4sWVc6P2/u1Lly5Jhw4dJH/+/FKoUCEpWbKkzoiEKVOmSIMGDUTk9T2MEyZMkNatW8udO3fkxYsXSm9tdusp27VrlzRo0ECMjIzEyspK5xyaUkJCgvTu3VuKFi2a6r5KbW9Z9+7dpUKFChIZGSmJiYkyfPhwKV++vIj8b7/j4+NlxIgRMmvWLImJiVGWL1q0SGcejpysXbt20rZtW+U3h7Z9zpw5I56ensr9qml9VmJjY3PUXCxv0v49Q0JCpHHjxqKvry8ajUZmz56tfK9qjR07VkxNTeXrr7+W4OBgSUxMlAcPHkivXr2kSZMm8vTp06zYBdXcvn1bJk2aJMePH5cnT55IuXLlZN68eRIbGys3b96UOnXqiKenp1y4cEFERDw8PJTvFO337dWrV6VRo0YyZMgQnby/+eYbGT9+vDJ6cP78+RnO/ZIdbN26Vbp27SqhoaGyYcMGKVeunNIL6u/vLzVq1FDOo2fPnpVKlSrJ9OnTReR/x9bZs2fF1NRUmVtC5PVnqVu3bsrv4KSkJFm4cKH8/fffmbl7aXrbOT8hIUGOHj0qVapUEU9PT0lMTJQ6depIhw4dlDQhISFSpUoV6dy5s4i8/p3q4uIiy5cv18k/ICBA9PX1dUapxMbGyvbt25VzzZMnT2Tz5s0685fkRJ9l8Kx148YN2bp1q87QrbeJiIjQmahH5H9fSj/99JNUqFBBDhw4ICLZ7wdKetK7iPDXX39JqVKlJH/+/OLj46Ps861bt8TAwEBWrlwpIv/bz5o1ayoftj/++ENcXFykY8eOcvfuXbl586Y0a9ZMvvzyy7fW5c6dO1k+vCU5OTndYbbh4eHi4+MjJUqUkLFjx8qGDRuUYdknTpwQjUajvNdur328kMjrxxy4uLhIlSpVxM/PT/r16yflypVLNe1/WnXKTpYsWSLlypVTHs+m/ffYsWNSqVIlGT16tBw9elRmz54t+fLlU34Ma4ekVq9eXebMmZMq+E1MTJT169eLqampVKlSRQoWLCje3t5y8+ZNnYmjnjx5IseOHcs2jzXT/n0GDRokDRs2lIcPH8revXvl5s2bIiLSr18/6d69uxI8njt3TjQajWzbtk3Cw8OlRIkSUr58edmyZYvORFcRERHKsDp/f3+pU6eOWFpaSvHixeX3339P9cP3yZMnOpN1ZCVt3Vq0aCGWlpZStWpVGTlypLJ+0aJF4uHhIVeuXBGNRqMzedPIkSOlfv36ygW7Q4cOiYmJicyePVtERJYvXy4ajUZMTEzE1NRUevXqpXM7RHaWmJgo8+bNE41GI5aWljJnzhxlIrPbt29Ls2bNZM6cOVKvXj2dCXmePHki3t7e0q1bN+U7xtHRUbp06SIRERGSmJgopUuXFldXV3F3dxd9fX2pVKmSbNy4MUv28108fPhQWrduLRqNRsaOHZvqdqeUtJ+x77//XgoVKqRccHvzHNC/f38pXry48v7gwYOi0WiUi5xv+37JbufZK1euKI9RetdgVvu5W758ubi5uaUakhwTEyMjR44UJyenHBUga7+XDx8+rFyUf5e/15gxY6RSpUpSv359cXR0lMKFC8vkyZOVyUtjY2Plxx9/lLx580qpUqXEw8NDjIyMpHbt2nLo0KGPuk/vK2Xgpr0IkJCQkOqYTkpKktWrV8vp06fF09NTvL295ezZs7Jy5UopWbKkzm09gYGB4uXlpRxnK1euFEtLy1QXgPv37y/ly5fX6dx4s/2fPn2aqY+P1Jb/5MkT+eeff0REdIblp3T79m357bffZNasWeLh4SGjR4+WiIgI6devn3I7iza/3bt3i4GBgfL93aZNG+ncubNOm8TExIizs7M0atTorXVM2VGSWZKTkyUiIkJmzJghCxcuFBHRuWiU8u82depU6dq1q3Tu3FmmTp0qISEhEhYWJq6urqluofz999/F3Nxc4uLiJCEhQRo2bChdu3ZV/uZhYWESFhYmhQoVUm6dSa9+n4JPOnhOeb9uShcvXpRq1aqJiYmJVKpUSRwcHN75ilnXrl2ldu3aygdUe+J68OCBFChQQOcekOwsrROMdl9evHghtWrVkq+//lr5YZbyKpGHh4f4+PiIyP8+CKtWrRILCwu5f/++JCUlib+/v9jb20uFChWUexDfnKk8ZZmZ5W33KL25XHvC0bbV77//LoUKFZJTp06luX2pUqVk3LhxOnl9//33UqJECSVwOn36tPTu3VscHR2lUaNGEhAQkGE9MltUVJQyU3zK40T7t3ry5IlYWFhI06ZNJV++fMpzdmvWrKnTS3716lUxNjaWxo0by+PHj2X8+PFib2+f6tg7cOCArFixQjkJX7p0SebNm6fMTq+Vle0SGRkp8+bNU2Y1TmvG/MmTJ4u5ubloNBpxdHSUy5cvS1RUlBQuXFi5QOfn56cEDPPnz5fw8HDp2LGjuLu76/SmPXz4UKZMmaLzPNqoqKhUF/rSO8dlNe3feMuWLWJpaSmLFi2SsmXLypIlS0Tk9czg3bp1k8TERClWrJhMmDBBkpKSJC4uTqpVq6b0Iou8HrWi0WjEzs5ORF4/U7Rbt246M5DnJKdOnZJq1apJ/fr15csvv5SBAweKyOtzQ7Vq1eTMmTMyatQopcdURGTevHlSsmRJ5fiLj48XZ2dnqVSpkhw8eFDCwsKkZs2aUr58efH19VUuaGU3iYmJyuclKipKBg0aJFWrVk03vfbY1n7ejh07JiVLlpSmTZumSvv48WMpVKiQDB8+XDn+wsPDZezYscp8Aill9YXajAQFBYlGo1HOi+9ysVDbXg8ePBB3d3cZO3ZsqnWrV6+WmjVrpvl9nJ2dOHFCypUrp8xynPJYelPKkVA1atSQX375RaKjo2XmzJlib28vBQoUkP79+0twcLAkJSXJ06dPZcuWLbJixQrlgmV2or0oumbNGtFoNG990kRcXJyYmpqKhYWFTJkyRVk+Z84cKVWqlM5TB168eCE9evSQNm3aSHJyssTGxoqJiYkMGTJEdu7cKQMGDJCLFy/K8ePHZc2aNamC46z6/tHWIzExUXx8fMTV1fWtowT8/Pwkf/78UqpUKeX4iY2Nle7du0urVq2UfUhMTJTIyEgpXLiwLFq0SEREli1bJuXLl5dx48bJ/PnzpUuXLpKQkCD79u1TgvaUsuq8Eh4erlwsffbsmdSvX19atmypkyYkJEQnkJ43b56Ym5uLh4eH0qYPHz6UevXqKfd0a928eVMMDQ2V+Xd++ukncXJykrp164qZmZnSK/3kyZOPtYvZyicZPL/tw5yYmCg9e/aU1q1by+3bt+XRo0cycOBAsbW1VX6sv23YX0BAgBgbG+tcvUs5NDu7Sq9NNm/eLAsXLpT79+8raZYuXSpFixZVrta/acWKFZIvXz55/Pixsuzly5eSO3duWb58uZLP48ePZe/evamuYmYnb/6to6KiZObMmVK7dm3x8fHReRRF8+bNUz0CJOVkN9rhlikvNNy9e1c0Go3ORZW0rhZnF/fv35eGDRsqJ9036xkTEyPu7u6i0WikePHiSnAXHh4uLVq0kGnTpsnUqVOlSJEiUrBgQenSpYscO3ZMRF6P9DA0NJT+/fvLwYMH5fHjx7Js2TLx8PCQH3/8Md1HLGWH4FD7w23YsGEikrpdQkJCxMrKSkxNTeWrr75S1u/fv1+qVq0q3t7eUqBAASlRooSMGTNGCYJEXk/WYmtrK5UqVZLFixfLd999J05OTlKtWrU0J4p7nwmW1KYt933+JsbGxrJq1SpZsmSJuLq6SmBgoHz77bfStWtXEXndO1SqVCkJDw+XqKgo6devnxQpUkQOHDggy5Ytk9atW8u8efPkiy++0Bn6nR29y98mLCxM+vTpI1WrVpVLly5JwYIFZePGjRIdHS358+eXx48fi7+/vxQtWlT8/f1F5PVFOHd3d2WUytKlS8XLy0tKlCihDN3Orm2TVpCj/aG2efNmKVu2rHKc37lzRyZOnChz584VkbSPs2nTpolGo5EffvhB6UGMioqScePGiZeXl84olezqXT8/5cuXl3nz5uks0wZ36R1n2rz79esnTZo0UX6raP8G2WV0yn+h/Y551yGfz549kzZt2ugMQdU+vs3JyUkcHBx0Rr1kN2FhYdK+fXudR8+ZmJjIihUrROT191KvXr1kxowZytBrEZEffvhBNBqNzsV57Sgf7fexVufOncXHx0cJqlasWCFeXl6SL18+6dy5c7a73fDSpUvi5eWlfPaXL18u1atXV4ZLz5gxQ5o1aya+vr5K3aOioqR27dpSvHhxnc/e+PHjpVGjRsooJ5HXFxSqVaumdAS8ePFCFi9eLI6OjuLi4iKzZ8/OFr9J3vTTTz9J586dlb/j7NmzpVq1avLPP//Ixo0bxdLSUmxtbaVt27ZK0H/nzh1xcnJKdQtRnz59pEmTJnLr1i1l2Y4dO8Te3l7Z9uXLl7Jv3z4ZMmRIjuk0VNMnGTxrHTp0SKZMmSJBQUFKkKQdVqC9F1O7rFWrVlKvXj0ReXvwnJCQIMbGxsoQQq3s+GEKCQnRuScjpTVr1kihQoWkdOnSUqNGDSlTpowy1GLWrFmpeghT7t+zZ8/EzMxM/Pz8dNZ5e3tLu3bt0nzOX3bpIXv69KmMHz8+zVnOX716Ja1atRIXFxeZN2+eDB06VBwcHMTX11dERDp27Cj169cXkbSH0V27dk2MjIyUk4t2fzt06JCqF1Uk+7RJSomJiTJp0iRxcXFJdf++1oULF2TSpElStmxZpUfn4cOHyn2L9erVk3Xr1un0fml/LK9du1Zq1aollStXlvz584uDg4PMmTNHIiMjU9UlO7VNdHS0jBw5Utzd3dOsl/aH7MiRI6V69epKu1y8eFFcXFzE1dVVDh06pHPV986dO0rAc/LkSRkzZow0aNBAqlevLsuWLcv2wyoz+vto69+xY0fx8PCQqKgomT17ttSsWVOaNWumDHm7fv266OnpKYHh1atXpXnz5mJrayt2dnayYsWKbDNEX+vNwCW9oDm9Ntq4caOYmZnJ8+fPZenSpVK7dm359ttv5YsvvpCgoCC5d++e1K9fXxnhExwcLF5eXmJvby/29vbi4OAgx48fV35A5hRr164Vb29vcXV1lStXrsjt27elcePG4ubmJjVr1hRzc3Px9PRMc3Z0bVtqn7VaoEABcXR0lKZNm0qePHnE0dEx3VnVs8O5JCkpSZYuXSrOzs7y119/pZsuISFB+ewsWrRIKlSooAy3tre3l7Zt2751f7TH4bp168TR0VH27Nmj7o5kAe15c+HChdK1a1e5f/++nD59Wlq3bi21a9d+6/nB19dXqlevrlygSTkqIbuLiooSe3t7nSCmadOm0qpVK/nll1+kTJky0rRpU3Fzc5PChQsr59CzZ8+KRqNR3muPl4oVK4qPj49yb39ERIRUrFhRubVM5PXxk7J3Wis7fIZEXt821rx5c+W99p7sAQMGyDfffCNubm4yZMgQKVq0qFSrVk25mKYdwp/y4sHBgwelevXq0q9fP2VZQECAWFlZpZoNOrv+RtF+3lu3bq08rUTk9SidBg0aSNeuXaVjx46ybt068ff3F29vbylcuLDS+dWzZ09p2LChXL16Vdl29+7d4urqKl988YXcvXtXIiMj5auvvpKGDRvmqFtfPqYcGzyn90e6c+eO3Lx5U0aNGiU2NjZSsWJFKVy4sBIAHT16VJydnWXdunXKNomJifL7779L7ty53+mqbE75waINZkVe11n75XH79m3x8vJSppQXef2jRk9PTy5duiQBAQGSK1cu5Z6PlLS9g61bt5bq1avrfJCy4v6O95WcnCxubm4yePBg2bNnj9SrV0/5wfXjjz+Kq6urToDj4+MjlpaWcuXKFfn111/FzMxMZyI0kdcXKbRBUMmSJaVNmzaZt0MfKOWPfu1nateuXVKxYkXlvva0LqKEhoaKubm5rFq1Stm+T5//a++8w6o6tja+DiKIUkUUROlFehMRQREQRRSwSzEKFoIVew92k1hi7yaxl4iJUWxREksg5sbeQKygotgFKdLe7w++PWHDoRmVg87vee6TK+fsNmf2zKw1a70rAm5ubmVE37Zv345Fixaxf+fl5SEhIQGJiYkf7Ln+C0VFRVIN1507d8LCwgKHDh0CID2k/fz581BVVWW5hgBYuYeSC5InT54gNDS0jBOn9PgjaxEKz549g4aGBtv9qigNomSorUQiwZkzZ1BYWMhK+w0bNow9r62tLXr16sXePVkVWHz79i1CQ0MxadIkAGV/n0ePHmHFihVYv3691AWowI0bN2Btbc0WO0IetK6uLl69eoW3b9/im2++gZGRERtznz9/jo0bNyImJuYDPd1/R5rj+cqVK+jUqROUlJRgaGgIT09PNGjQAI8fP0ZBQQFmzZoFZWVlTJs2rcq/eWFhIZKTk7Ft2zbMnTu33FQaWSAuLg5BQUGQl5eHpaUlpk6dKhLIK4+srCzMmjULcnJyUFZWRpcuXbBly5YqG335+fm1Yk6uDr///jt0dXWhpaWFxo0bY8CAAeU6B0pH/2zZsuVj3up7IT4+Hp06dRLpARw9ehQSiQTOzs7s2d+8eYPu3bujbdu2bP61srJiIl9CWwhzu5WVFRYsWAA3Nzc4ODhIXesB0ksY1RTCfWzfvh12dnaiz6KiotCiRQu4urqylLNLly7B2dmZrYFPnDgBe3t7Fo4NFLfLzp07UadOHfj7+2Pw4MFo3rw5wsPDpdoCQhkrWWTUqFEYNGgQ+3d+fj4GDhwIZWVlUfpGeno6LC0tmWjprl274OjoyDbDgOLnPH36NJo1awZbW1uoqqqiRYsWUsXPZL1c24eiVhnPVfHcenh4QENDA0OGDMGLFy+QkZGB2bNnQ11dHY8fP0ZmZiZsbW0xb948kZG0b98+WFhY4OLFix/rcd4rJXcxBS/s119/DX19fejp6UEikWDChAkAgN9++w3W1tYAio3qiRMnwtjYGJqamjh58iRev34NS0tLDB48WDTJ//bbb9i1axeA4vby8fEpU2MSkB3vU2lVdcEg8vDwgJycHBo2bIiQkBBmxE2bNg1Dhw7FzZs3ERwcDE1NTRgaGmLWrFl49eoVcnJy0LRpU4SFhbFQr1u3bmHs2LGsPx47dkyq0IisDbiCAIs0Hjx4gKCgIJF3tyTCs3h5eaFPnz7MmfDbb7+hTZs2aNu2LY4cOYIbN25gzpw5aNWqFaZPn17ufcha25Sk5Bhx/fp1dO7cGQMHDgRQ/m9qZWWFESNGsJ3306dPw8PDA82aNcPUqVMxbNgw6Ovro3379qK+UjK/U1beIWnY29sjOjoaAMqo15aHtrY2pkyZgsLCQuTm5uLIkSOi0Mu1a9di2LBhVT7fx+TKlSvM+VpUVITRo0dDX19f9J2CggKMHTsWDRo0QLt27eDk5ISWLVuKlFdLkpWVhYkTJzJxq8LCQkyfPh0TJkxgURqxsbHQ1tZmzhpZoLzd9fLGkpycHHz33XcIDQ1lYooTJkzAgAED2LkOHjwIOzs7ZtxURS29ModNTXPjxg0EBwdDVVUVCgoKUFBQEO0KVcTp06fh6ekJFRUVODs7w8jICEOGDPnAd/xxWLVqFfr06cN2UqsyzuXl5WH58uWwtbWFmpoatLW1ERAQUK7BV5qCgoIqOStkCaFdzp8/j0aNGolS5ACgadOmMDExYdFhQPFuoZubG9sU+frrr9G0adMy+gfXr1/HuHHj4OnpiUmTJsl0Wp00Fi1ahB49eojaZP/+/dDS0mJzs9B+P/30E+rXr8/aoGPHjggLC2MOKGG8+P333zF58mT07Nmz1oYgBwcHY+LEiaK89M2bN0NZWZlthAjPu2TJEmhrawMo3vRyd3fHmDFj2BpZ+N7Tp0+xf//+clM4P2dqhfFcHc/t/v37IZFImLQ8UDx4qqqqstyh4cOHw93dXZRPOHLkSDg4OJSbdymrlLfQSEtLg4eHBxQVFeHv7y9aqC5fvhyWlpasXFDHjh2xY8cOkZd63759MDQ0hIODA5YtW4aePXuy/DpZWaCUR+kJOS8vj/3t7NmzCA0NhYGBAcurE44ZNmwYVFRUoKGhgf79++P48eNlQtBjY2PRpk0bGBkZwcXFBYqKiujWrZso5KU28fLlS6xevRorV64UTaKLFy+Gubk5Cz8u2aZCn9u6dSuaNm0qUhi/cuUKPDw84OzsDE1NTaYsLut9piSpqakYMWIE7OzsMGDAAPzyyy8AivtRdHQ0rK2tpQoyCRPP3Llz0aJFC1EO2v3797F8+XJ0794dPXv2rDBsU1YR+sCaNWvQrFkz9vfk5GSsWLFCqqdeaJOJEyfC2tq6zM6iLDsJBGJiYiCRSFjE0T///IM6deqwEnRAcT5Yq1at2LsAgIUOlhdSevjwYWhoaDAHSul3JCMjo8Ld65pECPssOf9kZmZi5cqVGDVqFH7//Xc2dpb8jTMzM2Fubo4ffviB/e3Bgwfo27cvy7urbp+QpZ2PX3/9FWFhYYiOjoanpydOnjyJtLQ09O3bF2FhYRUeK/z+O3bswLhx45gjf8eOHWjcuDGA2vG+lOTevXu4d+8eGwdWr14NOzs7VoGhKs9z4MAB+Pv74+uvv8abN2+wbds2dOnS5bNY0L98+RJKSkos1FhwLo4cORLGxsaicO709HT4+/sjIiICQPGco6SkhP3797PvCH2s9LqxNvQr4d4XL14MZ2dnUbWO9PR0+Pr6onPnzuxvRUVFSEtLQ/369ZlI2Pz589G2bVu2g1qRo05W2qQ8BXEBoV3Cw8PRuXNn0YZWcnIy2rdvX8b5lpCQgHr16rEohaioKLRq1Qp///03ANl3TsoCMms8v6vnNiMjA5qamswwEn7sAQMGwMXFBUCx4EDPnj2hqqqKRYsWYcSIETA0NGQ1y2ojf/75J+bOnYtjx46xRUtubi769euH3r17i+pX/vzzzzAyMsIXX3whckIUFRWJFn///PMPoqKi4O7ujrCwsDLlYGRl17C8xdOePXvg5eUFb29vTJkyRRTu1rVrV3zxxRcihcalS5fC2tq6THmXmzdvYv78+exaGRkZ+Omnn7B69Wqpypw1NegK171+/Trzyufl5ZU78C5cuBCqqqpwdHRk4inCoubPP/+Es7Mz23GTdo78/Hxoa2tj6dKlZcKcExMTZWrhf/HiRXz11VdMYba8Hc4nT56gdevW6NChAzZs2IDAwEA0aNAAO3bsAFBs8FhbWzN1fmkh7WlpaVBTU2Pe3pKU7huy8P5UhdK/v6KiIsaOHQs7OzsoKysjJCSkTDoD8O/z3rlzBxKJRBTOLusIi5a3b99CV1eX6VxkZGTAxcUF4eHh7LuzZ8/GgAEDABSXFevVqxdUVFTQsmXLMgrpQpukpqaiXbt2LM1DlkIkpfXLwsJClt4j1EEFikNGZ8+eDW1tbbRs2RKBgYFo2LAhxo8fz/qNMCf9+uuv0NbWRmZmpqhPfffdd7C2tmYOitryXpSkqKgI0dHRUFdXL/PZV199hTZt2rA5tDrP9/r1aygrKzNnv6y3zZMnTxAdHQ0DAwPo6OjAxsaGhZM+efIErq6umDBhQqV9vXQkncCzZ8/g6emJzZs3y3RbSFuXZGVlsUiSqrzrqampcHNzY1GDwnt09epVVu6wJCWjgoDiHOfSIqcl+djtJ+16Z86cEQl2lYfQXlevXkWdOnXKOE+io6Ph7OwsSuG4dOkSjI2NWXrUuXPnYGxszKo+SLu/jzkGV2cNnZ2dLbWsrnD8vn37oKKiUqZW/ahRo2BtbS1aq86fPx9WVlZs0+e3335DeHh4rd0Eqglkznj+L55bgQEDBsDd3V20oI+Pj4eCggJ74V6/fo0ZM2bA09MTvr6+MhUaJw1p3qeioiLs3bsXdnZ2aNSoETp16gR1dXVERUWxF+iHH36Ak5OTyCBMS0uDp6dnGYW9v//+G15eXiIl4KqE0NUUpcOyBZ4/f47g4GBYWVlh/PjxWL9+PXR1dTF06FBmVH7zzTdwdXXFb7/9xo5LTEyEj48PW+S8evUKZ8+eZcqD5eWPyVKY7YULF2BgYIC5c+eW+52ioiIkJSXB2tqaOZlSUlIwYsQI6Ovr4+7du8jMzMSgQYPQrl07qecQ+oWvry+cnJykGk5AzbeNcO3du3fD0NCQldUSKB2yNnfuXJiamoo8+sOGDYOdnR1SUlLw5MkT9OzZE926dZN6PaE/2tvbY/z48VLrXtZ0m6Smpko17KvCzp074e3tjbp160JLSwtbt24tk+NeGqFNFi1aVG4/qUlWr16NX3/9tcLfJCoqCg4ODmzxunTpUqipqQEo7mPBwcFMX0NHRwcREREiR6Q03r59i6+//pqV+KgNhIWFQV1dHS1btmQ7o6mpqZg1axaL0ACKcyubNGnC1MIFAgICmJOhJKdPn4axsTFL75CV8bQ8cnJyEBQUxPIpBebPnw9nZ2cmUiQYfsePH0ebNm1Y7dTqGi2+vr6iOumyRlFRER4+fIiEhARIJBK0bNkSmzZtwuXLlzF+/HhIJBIm0jp8+HB07NiRqYBX57cWvhsUFIQhQ4bInMJ8RSkMQPG6Q0NDg61DKnv2zMxMjB49mm38AP/2HRMTE7Rt25alkF24cAF6enqisqt37typ8VSYygxEd3d3Vmu5qjRr1kxUhgsoFvoyNjZGr169mJG5ZMkSmJqaiuYdISe6JqlOtMyBAwfg5eUFLS0tjB07VqpwGVDcV5SVlbF+/XrR3/ft2wdNTU14eXkhJiYGv//+OxwdHVk+POfdkCnj+X15bk+cOAF5eXlROSkA0NDQQFRUlFShn9rCmzdvkJSUxBZxc+bMwfTp00W5G66urixs/fHjx3B1dcW4ceNEi/ZDhw7B0NAQNjY2GD16NNq3bw8tLS0MHTpU6m5qTS/4K+LmzZtYsGABYmNjkZeXh7dv32LhwoUiL9qiRYtgZmbGJvCrV6/CyckJ8+bNE50rMTER9vb2sLGxgYWFBZSUlNC7d2+RYIeArLZHQEAA+vXrhzdv3uDRo0cYM2YMhg4dKhJ72LJlCzQ1NZGdnc36TmZmJrS0tLB8+XIAwPfffw8zMzMWMlbyXRHeoatXr0rN8ZYVhPvMzs6Gl5cXhg4dirt372Lo0KHQ0NCAs7Mz1q1bx9I1BgwYgE6dOgH4d+F7584dNGzYkO3KL1q0CC1atJCatyerSq4lx7zdu3dDIpGIHASVkZCQADU1NZiammL69OlYuXIllJWVP8StfjSE/ty/f3+m5VCSPXv2oGXLlvD398egQYNEztekpCTUr1+fiXdFR0ejcePGZaowZGVlMcXbiu6hpinp5MnNzcWKFSswYMAAtggV3oXIyEjY2tqib9++LBLs9evXbEF6/vx5DBw4EI0bN4acnBwmTJjAUobu3LkDXV1dNg6lp6dj/fr1+PPPP5GTk4M1a9bItPCXgPC+C1oiQlQKUOyIMTU1xdWrVwFANLYGBQWhe/fuUqtRVIY0bRFZ4NChQ+jYsSPq1auHFStWIC0tDUpKSmVUz7t06QIvLy8AxcaAg4MDC92vzjwqjGN37tyRKTE0ac8QFxeHsWPHYs2aNUxX5cSJE3BxccF3330HoGqbEz/99BP09PTYBo9gDK9YsQISiQSenp4IDg5G/fr14e/vLxPtIq09nj17hm+//RZhYWFYvXo1m39iYmKgqqpaJaNWOO/06dNhbGwsynvPyspCcHAwVFRU4OvrCzc3NygoKODbb7+V2bXa9evXMXLkSPj4+GDq1KmIiYlhfaKoqAgxMTEwMjLC+PHjER8fj4SEhAp1hoYMGYJWrVohKSmJffb48WN07NgRurq6GDRoEJo3b46wsDCp4oyy2k6ySI0Zzx/Sc1tQUABjY2PmmSqZK7Fx48Za1UGEez9+/DjatWsHNTU1REREsN3h27dv4+3bt3jz5g3WrFkDR0dHKCgowNfXl3llhw4dCj8/P1y+fFl07suXL2Pt2rXo3bs3oqOjZVLdtiJu3rwJPz8/NGjQAJ6enli+fDnbcc/JyUF2djbmzZsHExMTqKurM6+kEJEQGhoKX19fNgALC56srCycPXsWv/766zstdD4mhYWFZSbgxYsXw9PTE2vXrkVAQAB8fHwQEBAAFRUVFja7Z88eqKmpsbB9YULu3LkzeyfPnz8Pb29vjB8/HoBsRyGURFqbAMVCRYGBgRg7diyGDRuG48ePY8SIEdDV1WUL4NmzZ8Pc3JwdI5zH2NgYs2bNAlDs4XZ2dmbjS3ntUtO5mPn5+Vi3bh169eqFUaNG4dSpUywMuXHjxli5cmWVz5Wbm4uEhAT2PuTn50NLS4uVYJP1slrSqOi3uXjxIgwNDTFu3DgkJCSgf//+kEgkmDp1KoDi9vD392el6xISEmBqaoopU6awc+Tl5WHz5s3o3r27KD1E1hDqpgqL2SNHjkBbWxsSiQQRERFsHsnNzcXMmTPRr18/REZGokOHDqJ5+IcffoCFhQX69u2Ls2fPIioqChYWFmyuWrt2LfT19bF161a0b98ecnJyohrPssr9+/fh5uYmcrCkpqZi7NixcHd3R0BAAHMInDt3DhKJRBQ6KfQzoe7qH/9fe1dWHCfV5fLlyxg2bBh0dXWhqqqK0aNHi8JuAwIC0LlzZ5FDpnv37jAzMwNQPDe3b98eX375Za3TmCmJtB3Vp0+fYvTo0dDQ0ECTJk3g6+uL5s2bw9jYGBcvXkRWVhYGDBjAHAmVnR8oNjpDQkJEu89AsfNJIpFg27ZtWL16NctXrSnK23WPj49H69atIS8vD2dnZwwePBhKSkpwc3NDVlYW8vPzoaGhgRUrVlT5Wi9fvmRzcsl+NnPmTLi6umLr1q04fPiwzPav7OxsjB8/HlpaWggMDMQ333wDb29vyMnJoWfPnux7jo6OGDt2bKXnE/rK7du34ezsLFLXBorrWX/99deiPHHOf6NGjOeP4bkdMWIEGjVqVKXSU7LOpUuX2A7xhQsXcO3aNVE+6dmzZ9G6dWs4Ojpi2bJlmDNnDiwtLVkY3dGjR+Hg4IDevXtjwoQJsLe3lyp4BMj2DrOA0CcmTpwoKo1U2iM3adIktG3bFuvXr0dRURGmTJkCc3NzVr9v3759cHd3h6WlJeTk5ODt7S118K8NbQKA5fMmJibC0dERVlZWbCesqKgI/v7+6NatG9LT0/G///0PlpaWLHxXeKfGjx8PZ2dnAMXv3JAhQ2BqalprDOeSvH79Ghs3bmRl6eLj42FoaAg9PT1RVEpAQAD69u2L7OxsHDx4EIaGhkzQq7CwEC9fvoSVlRUznB49eoQvvvhCVBtTlrh37x6Cg4MhkUhgZWWFcePGwcrKCo0aNWLpG4IGxH+pnxweHg4nJycAtcexUh5Tp07FmjVrWHsMGjQILVu2ZP/Ozc1FVFQUDA0N2U7qjh07ULduXRZlsHbtWqipqcHLywtDhgyBiYkJ9PX1sWrVKpmeh0rXTX348CEiIyNhZmaGHj16iMRmfH198eOPP2LDhg2ws7NDXFwcgOKqA61bt8a4ceNYm23atAkNGjRg+YYjR46ERCKBtrY2xo0bVyY3D5DNnY/s7GwEBQXBzMyM7SA+e/YMQUFB+PHHHzFu3Dj069cPz549w507d6Curs52CUuWtvnnn3/g4eGBadOmAZDNZ62IHTt2QF1dnSnKa2trY8aMGexz4Xn27dsHJSUlZtQcPXqURTQJ48S0adPg4eEhEt3Lz89HYmKiSGhR1pBmID579gzz5s3D4cOHERcXB4lEgtmzZ7PPExMToaqqyt6jjRs3wszMjDkcquJEuX//PrS0tLBs2TLR+ldaasjH7lfS1keHDx9GaGgo0tLSMHbsWNSrV09UyWbDhg1QU1NjkYBhYWFVno+E9lq5ciXatWsn0ip68OBBmVB+WXFS/fTTT2ztuW3bNhgYGJQps7Z06VIoKiqyqJ6AgAB4eHhg/vz5mD17NpYsWYJly5ZVmK6wZ88emJubi8L3Szu3ZUlfo7byUYznmvDc3r9/X2pNMlmiqi91QEAA2rdvX8bgFdolPDwcHTt2ZLsbZ86cQf369VmOVEFBAQ4fPowOHTqga9euUkMUZWWAyc/Pr9JLnZaWBhUVFWzdulXq59evX4exsbGovvDkyZOhrKyMmTNnsmslJSVhyZIlUsMFa8PgcvnyZfTt2xfa2trw8vJinsXw8HCoqqqKRDW2bduGVq1aISYmBnl5eRgwYACsrKyY0yE9PR12dnaiBdHFixdZFIistUd5O7vPnj1DWFgY6tWrBycnJ4wePZrlCXXt2hX29vYiR8vSpUvh4uKCP/74A7m5uejZsycsLCwQFxeHt2/fYsWKFbC0tBSlAUjLZa5Jzp8/j8DAQMTGxuLAgQNo0qSJ6He8dOkS2rVrh9atWwMATp06BTk5OZG+QXW5cOECJk6c+F9v/YNQ1fFMWAgHBATAzs6OlT8ZOHAgU24V+ti1a9dQp04dtuC5f/8+tLW1RXVDExISsGzZMvTr10/m68pWVDd1yZIlsLe3x6ZNm+Dq6sqiLEJDQzFt2jQ8evQIHh4eLG/u7t27UFFRYakNmZmZCAgIgLy8PHr27Im8vDz8888/ZWq7y3Ld1JK8fPkSurq6iIyMZM4SV1dXbNiwAY8ePYKXlxfmzJmDtLQ0ODo6srDckuNTYWEhIiIi4OnpKdORCOVx7do1rFixghlvkyZNYrvJJZ8zOzsbjRs3Rrt27WBsbAw1NTVMnDgRmZmZotrvTk5OWLZsGR4/fozly5ejZcuWkEgkWLhwocxFskibZ2JiYtg9Ozs749SpU8jNzYWZmRkWLFiAnJwc1ladOnWCm5sbcnNzcf78ebRt25bViq/M8Si02aZNm+Dp6cnWL5Xd34em9DVv3ryJ8ePHQ01NDY0aNULfvn2Rl5eHQ4cOwdHRUWTM3b59G+bm5vjiiy8AFAuUVnU+Eq5bUFCAtWvXwsjISKQoLnxHltYru3fvhrq6OosOsLa2Fmk4Cb9xdnY2IiMj0bRpU9y6dQt37txBz5490aZNGwwePBi+vr6sFG/JMmWl2bBhAzw8PERVDWrLJlBt4aMYz9xzK6aquzTC85mbm7NwdeFY4b+PHj2Ct7e3SExk4sSJ0NHRgbW1tSgnpDYsUgQqy/G6desWVFRU8PvvvwP417MmtNk///wDFxcXFmp78eJFBAYGolWrVvD395caziNrAy5QcZmCBw8ewMPDA926dcPp06cRFxfH8tV37twJCwsLUVSH0FeGDRsGoDhvrHnz5rC0tERERASsra3h5ORU5fqZNUVlC+6lS5fC1dUVJ0+eBFDsFBDacPHixWjVqpVIKO7atWtwc3NjO8tPnjxB+/btYWpqiqZNm6Jhw4ZYtmxZmWvWdH9JT0/HggUL0Lx5c6iqqsLLywvJycm4f/8+QkJCmIqz8G4MHjwYzZs3Zwt3IyMjNpZ+rgi/6blz5yAvL8/y96dOnYp27dqJaom+evUKJiYmiIyMBFD8bn7xxReisl21EWl1U//880+4uLhg1apVOHXqFNq0aYN58+Zh2rRpiI6ORlFREaKiouDm5sZ2Qdzd3WFmZobw8HDY29tjzpw5iImJkbo7VpvmIoHly5fDwsKClbwcPXo0e8cOHDgAY2NjxMXFwcTEhOlGCAjPu2LFCvj4+Pwnp5WsEBsbCzU1NbZ7XHKemjx5MiQSCTZv3iwqk1mSTp06QVlZGfLy8tDW1sbkyZOlRiPIEkePHkWXLl2goKAAiUSCsLCwMqGw4eHh8Pb2ZsrxANC+fXt0794dQLFa/+jRo+Hs7Cx1/hD6ivBZye8cP34c/fv3lxltgBcvXmDmzJnQ19eHRCKBRCJhjiOB+/fvo0+fPqLoljt37kBDQ4MZd4WFhTAxMZE6H1U2VmzYsAHTp08vUwu7pnjy5Am2bdvGoo0yMjJgYmLC1qI3btxAs2bNmHO7tKNIEN0TIuYEhHl77ty5sLW1FfUvaZw7dw579+6t9VFhsspHC9vmntuy7NmzB1OmTEF8fDx70UoPps+fP0dgYCAbeKV5ZCMjI6Gnp4cpU6YgJCQEvXv3xtq1axETE1MmXFCWvU9v377F8uXLYWdnB3d3d8yZM6dc4aWkpCS0bduW7XyUHGCFXcExY8ZAR0cHtra2aNCgARYtWoTr169LbcOaapOqLiKzsrLKeBrHjBkDY2Njqe/C06dP4erqivHjx4uuMX78eHTs2JEJoCUmJmL16tXo06cPVq1a9Z/CeD8EFf0ut27dwsqVK3H27FnWz9++fQszMzOWJ1T6t05KSoKTk1MZpc7BgwejS5cuohJf8fHxzACXFQoLC7Fs2TLY2tqyxYq0UiRCne6SpS3c3d0RFBTEfuPo6GgYGxtLdVTV9gk3OTm5jLJ6Zejq6rL8/j179sDJyUnkuRciepo1a8b0IU6dOoXp06fL3E5ZVaioburLly/x5ZdfMrX9ffv2oVmzZlBWVsa2bdsAFEeyuLi4MAddUlISvvvuO3Tu3LlMeOmnwPPnzzFmzBhoaWkhJSUFGzZsQI8ePdj7FBoaiqlTp0JBQYEJdpY2hGQ5fL+qCM9y9+5duLm5YfDgwQDEY+1ff/0FOTk5kaJ2yR1DoDhHfty4cVUqUyQLhISEoGHDhhg8eDAuXLiAli1bshJSwL/6PHFxcTAwMMD+/ftx+PBhuLm5QV1dnaUCAcUh8BYWFkwzIiMjAydPnsTw4cNZBYzy5r6srCyZWMPdu3cP3t7eaNGiBXbt2oXDhw+jdevWLIy65ByyePFiWFpa4tSpU5gzZw7U1dXh7u4uGnO++uorGBsbs3ckNTUVq1atQps2bSp16MvSWLN48WIYGxuzMmKLFy+GiYkJE3K7d+8etLS0ylXPf/ToEZo3by4qOSY4BtLT0xESEsJKv3Fqjo+a8/y5eW7LW4D+9ddfsLKygr6+Pry9vdG4cWOEhIRInVgLCwuxaNEi6OrqiuT2CwoK8Oeff+Lly5dIT0/Ht99+CxcXF4SGhrLcV1mkokXm5MmT0aJFC6xYsQJz5syBjo4OunXrxhaqJSeMnJwczJs3D5qamiKjUlg0C0JYBw4cwMqVK8uttSorlBYfKame7uHhgcaNG6Njx46ieo89evRgYU8CJct3DRs2DB07dmT6AUDxbkHpcPbSyMqukLCwKM2dO3cQGBgIZWVluLm5wcTEBMHBwXjx4gXu3r0LCwsLJoYlzXvft29fUTkLoDjv097enuVwlkYWjMnc3FzMnj0benp6+Pbbb5GWlobAwEBERESwlA7h/Tp58iRatWqFmTNn4scff4SxsTGaNGki2nFPSkqCnJwccxA8ffoUu3fvRqtWrdgYXdsoWU1AIpEgOzsbRUVFFaaDCG02depUGBkZ4dmzZ3jx4gWGDx8OdXV1bN++HVeuXMHo0aMxe/ZsNGrUqNIyVB+LD1k39ccff4SZmRnrHzNmzICamhr27NkDoHisdXNzEwncVHSdT4HMzEw0bdoUY8eOxcSJEzFy5EhmAPzvf/9DWFgYJBIJK2X3KT17ad6+fYu5c+dCW1tb6ufm5uafRGSL8I6lpqaK3rfFixejadOmUvNP7e3toaCgAH19fYwfP77MrmhSUhK6du2Kbt26YeHChTAxMYFEIkG7du1kzmFbHvn5+WydJdCpUyf079+fzUfCvHnq1Ck4OjpCIpHAz89PFBEnkJycDEVFRURHR6Nbt26oV68emjZtioiIiDLXkUWEvnH58mX4+Phg8uTJKCgogI2NDbNnhO9YWlrC09OTRVqUXF88ePAAjRs3ZpFwV65cQUhICDp06AAlJSV4eHhIrf7C+bh8VOP5U/Tcls59lLazK/w7Pz8fhYWFiIyMhKenJ/Ly8pCXl4eTJ09CTU0NS5culTrZ3r59Gw4ODvD09MTu3btx9+5dzJ49G7169RKJMJSmpibuV69eMWEiwSgsfS/37t0Ttd2VK1dgaGgoWrSfP38ezZs3F+UUluTx48dwdnaGkZERxowZgzFjxkBPTw9ffvml1N1YWdx1v3XrFmxsbEQ1UoX83KSkJDg7O2PMmDE4e/YsfvnlF1haWjIxiY4dOyIsLIw9qzTRDmdnZ5GgRlZWFjZs2FBGWb2yWowfm4MHD0IikTAxuLi4OKYG/O2338LDw4M5k5KTk9GqVSuMGDECRUVFsLa2xldffcXCBYXnEvrb5s2bYWNjg+3bt7PrvXnzRiZKfFRG6V3ir7/+Gm3atGFGv2AIPn/+HIMHD4ZEIkGrVq3KOCMF3N3d4enpiYEDB0JdXR1qamro06ePqNRFTVJZ3dSKKCmQJiBEspQ8p/De3L9/HxKJBLGxseyzfv36wcrKCoqKivDy8pKJigQfq27qpUuX4OXlxdI8srKyyvwWsbGxSE5Ortb91VaEZ1q1ahW8vb1hY2MDf39/UZucOXMGJiYmojH3U+bUqVPQ0tJiVRxKOsenTJmCBg0alFuXVhapyvpA+M6DBw9Qt25d9uzAv88/c+ZMmJmZiQTRSq4/8vPzMXr0aEgkEpibm2PJkiUyVY6suu+v8NzffPONaD4S3g1hPiqtGF56PHFxcYFEIkFISIjMOCjfhcjISAQGBmLq1KlwdXVl6XSC/bJo0SKoqKhg9erV7BihzWNiYiCRSFhofnZ2NhYtWoSFCxey9RCn5vnoatufkudWKPEhrUO/ffsWixcvRvfu3bFgwQK2MH/16hV0dHSYmIzwwoSFhSEgIKBccabLly8jMDAQLVq0gIaGBuzt7bFz584y35MFA3H58uUICQkpEwKclZWF7du3o3HjxjA0NERISAjbFU1ISICiomIZL263bt3Qv3//Msaw8IwpKSlYuXIlOnfujK5du7JQGWnflUXevHmD7t27w9vbGxMmTIChoSE2btwIoHjx0a9fP/bd27dvw9TUFAYGBkhPT8eiRYvg4uLCdhOFiUgoKZSbmwsbGxsMHTpUpsKapCG8B8J/Hz9+DCsrK7Ro0QISiQQtW7bEtWvX8PLlSzg7OzOn0Z49exAYGIg6deqw8MEJEyagdevWIsHAlJQUrF+/HkCxmnCnTp3KiIwANddXqntdYbFy9epVODo6lqlXDhTngpmYmLAFnGCIlrzWmjVr2G5A6dqsNYm0xduhQ4cqjTgqLCxkC5SxY8ciMDAQWVlZ+Prrr2FiYoI+ffpUeD0HBweEhISwnY7CwkIkJyfXuGOlJuqm5uTkYMqUKXBwcGCl7ADZiUypKV6+fIkZM2awtAnBSSfL88z7RnjWx48fsyoOgNgYunfvHr755huZSwWSxrumXfj4+KBXr17s38LzX7lyBbq6ukxpviRC2926davMjrQsrN/eBWFMqGg+Wr9+PczNzZlolrRxpGR0Zelz1waEe92yZQvs7OwgkUjQpk0bps0j8OLFC3h4eEBdXR1//PEH0tPTARSLcLZv3x6TJk0qtx/UFpHFT52Pajx/ap7bkiU+hMH33LlzWL9+Pb7++mu4uroiKiqK1WYWykvp6Ogwj5MgXPXzzz/DyMhI5KmUxqVLl6QOMLKA8Pt2796d7Y4WFhbiyZMnGD16NEJDQxEZGYndu3ezkkD9+/dHdnY2UlNTUa9ePTbICLuECxcuhI2NTaWLV2liTrJE6drDwv3euHEDmpqakEgk8Pb2FtWWdnV1xcSJE7Fw4UI0b94cjRo1QmhoKFObT0lJgY+PD2xsbHDo0CHcu3cPmzdvhoeHB/NaXrx4UWbzMcurx1xUVITNmzdDIpFAWVm5TP3Khg0bom3btmjSpAn09fUxduxYXLhwgX2enJyM0NBQKCkp4auvvsLMmTPh4OAALy8vUYm3T4XevXujV69ebFdU+L3Pnz8PDw+PCut05+bmymz/AIpTXIKCgqCkpAQNDQ2cOHGiysd+++23kJOTg7KyMtq0aYM1a9aUKyojtMHixYtha2tboZLpx0IW6qZu3boVhoaG1Wr3z4Hnz5/Dzc0N3bp1q7BszKdOYWEhVq1aBYlEUqt2mMvj4sWLiI+Pr/KYuGPHDigrK0uNSPHw8EB4eDgzjMpDFo2hX3/9lYknVjfyp7z56MKFC/D09MTIkSMrPa+slVJ6/fo1Ll26VGm/KLmp4+fnBysrK/j6+qJBgwbw9PTE0aNHRc4THx8f1K9fH+3bt4eDgwMUFRXxxRdflEkzLHlujmxQI3Wea7vntqISH+Hh4WjcuDF8fX2RlpYGoNjj5uLiwgRsgoKC0KZNG9G57t69Czk5ObZ7UBmyOOAKjBo1SiRokJeXh759+0JVVRVff/01+/vGjRvh5OSE2NhYFBUVwdPTE4GBgaJzzZkzB3p6ehVeT2jD2uK1TUpKEnnuBcVkoeay4KmfMmUKJBIJAgICsGnTJtEiTdhde/ToETp06AA7OztoaGigefPmWLRoURlREVlul4yMDPz4449Yt24dM25zc3Nx/PhxNG7cmOU+FxQUICMjA/369UOTJk1w8eJFkWr6s2fPWCRDfn4+5s2bh4CAALi6umL16tXMKVGyv8gKSUlJ5apvloew+NiwYQOcnZ1Z+KDw96ysLIwbNw42NjYybSBLY82aNWjUqBFUVFQQGhqKU6dOVem4c+fOoWfPnlBTU4OVlRXU1dUxffr0Kl9XFt4TWaqb+uLFi8/aOKwIWRo/apJz585h6NChZVSnZZHyfrM9e/ZAX18fDRs2hIWFBbp168Yc0BUZea9fv4aamhqLagL+Hb/nzJkDa2trmUmBqU5/7d+/PxwdHQFU3cFa2Xz05s0bRERElFnj1QYmTJgAf39/tj7Py8urtD0nTJiAdu3aISUlBQkJCQgMDISqqiqcnZ2xadMmVsrswoULWLp0Kb7//vtylek5skeNGM/Ap+G5lVbiIzY2Fs2bN0dUVBT7W1paGvr06cPCe44ePQqJRIIDBw6wxf+kSZPg7OwsM3L7/4Xg4GBMnDhRtIOxZcsWNGrUSCS/n5iYiM6dOyMiIgJAsbiXnJwc5s6di5SUFJw7dw52dna1TrxI2mR77do1fPHFF2jSpAksLS3Rr18/toP8+vVrDBw4EM7Ozuz7RUVF2LlzJ+rUqVNGafL333/HkiVLmGc3NzcX165dY8qmsoYg2FSa+/fvIzIyEioqKnBycoK1tTVcXFzYpJuamoouXbogICBAdJ61a9dCIpHg9u3b7LwvX77EpEmTsGzZMpFBXTLcVDiHLPLPP/9AIpGwd6YqRo/wLA8fPoSLiwsmT55c5rNNmzbBzc1NpkUEBQoKCtjvOWzYMNSvX7/aOV7fffcdhg8fzt6tb775Bg4ODu/5Tj8Msl43lcOprVRk6Ny9exetW7fG9OnT8eLFC8TGxsLHxwe2trZVOndYWBjat2/P5v2SGhs1rdHzrvoDFy5cgIKCQpmSnqV1REpfCyhe77q5ubE61iU/E4TEagvCc545cwaenp6shG5Vjtm/fz9at27NIoAKCgpw7do1REREoH79+vDz85Oa515bNoE+d2rMeAZqr+e2ohIf6enp8PPzK6NAKizihMVMREQEdHR00LVrV3To0AGampqixZAsUlHNYeDfdgkPD0fnzp1FA8ONGzfg5eWFESNGiI6ZPHkyWrVqxQzBWbNmwd7eHsbGxlBQUEBoaKhMhqmXFooDyvZnwRC4fv06evbsiZCQEPzxxx/4448/EBYWBktLS/bdXbt2QUVFheW8A8U7sm3btoWzszOWL1+Oa9euYcGCBXBycsLo0aPLVaCsqfeqtFCcNG7evMmcZbGxsRg8eDD+97//ASiemEeOHMmiOfLy8rBq1Sqoq6uzSVxYDPj6+qJ58+YYOHAghg8fDn19fTg5OeHQoUNSBftqcqyp6kRoZWVVxlEkCI2Ud//CuSMjI+Hn58ccKELfq+nFW2UUFhZKdawkJSVBXl5epA6ekZGBb775BseOHSvzfWmq6kDxzmndunVrhfMA4HVTOZzqUp2x/cCBA9i0aZNoTREbGwtFRUUWKQgUG0tqamrYu3cvgIp3nw8fPgyJRFKm7m5NRThJS/d4+fIlU7GuSPQwPz+fHWtlZYWNGzfi/v37CAsLg56eHtauXVvptQGgV69e8PPzY/NXed/7WJQslVYdSqaWdevWDatXr0ZBQQGOHDmCNm3aVFi15Pnz5+jTpw969+4tug8APCz7E6BGjeea5EOW+IiOjoa7u7sorO7EiRPw8PDA3LlzARTvNp46dQrDhw/H9OnTpb5MH5PqGBhCjnJphOP37dsHFRUVJsMvMHLkSHh6eoqO/fXXX+Hi4iIqLfTo0SMcO3ZMZhf+FQnFvXnzBkuWLEFgYCBTOH7x4oUorOvBgwcYMWIEJBIJjh49ys5pa2vLcsUFbt26hcjISLi4uEBXVxc2Njb44YcfZFKEpbRQnPCePH/+HFOnToWuri7s7OyYINqjR49YSNvZs2cxcOBAaGhoQCKRsHfqf//7H/T19Vk4qsCLFy+we/duDBkyBL179xYpnsoChYWFWLduHWxtbUX1PUuTn5/PjMdVq1bB2tqahVvr6+ujV69eFU6qwju3c+dOWFpasv5UGyj9XKdOnUJwcDDLETQyMsLIkSOxY8cO+Pj4QENDA0ZGRiI17IoQFj3GxsaidBFZhddN5XCqRnXWK0lJSUhNTUWbNm3QtGlTmJubw8TEhM3f8+bNg7u7u2i9kpGRgW7dujEHVUXXKioqEpWDrCmkzRN79+6Ft7c35OTk4ODggLVr11Yph/nFixfw9vaGgoICtLS00Lt3bxw+fLjScUE4d0pKitQNhpqmdPWe6jB69GgYGhqiYcOGMDIywpAhQyp1yk6aNAmurq6iigQl+xI3mGsvn5Xx/LFKfBw/fhxt2rTBggUL2N9evXqFnj17omXLluWeqyZ2x6rjkTtw4AC8vLygpaWFsWPHlisQkpmZCWVlZZHBCAC7d+9G69atRQqUKSkp6NSpE0aNGiX1XLIYwlJSKK7kbxYXFwdjY2PY2tpi7ty5WL58uShs+PLly/D19UXDhg3h7e0NCwsLdOrUCUBxm02dOhUaGhp4/Pgx4uPj8dNPPzHD6t69e2XErmSlXaQJxQmTaEFBAUaOHAlXV1ds374d165dYzvNAhMmTICBgQFCQkIQExMDW1tbppz96tUrREZGokmTJli3bh38/PxE3l5pavM1SVxcHIKCgiAvLw9LS0tMnTq1SjUqs7KyMGvWLCZw1aVLF2zZsoWVVqqM/Pz8GleErgxp/fXSpUsYPHgwGjRogHr16kEikbDc/+XLl0MikcDY2BiTJk2qsCyfNIQ+WFtE4njdVA6nfN5lRzU9PR0SiQQ+Pj749ttvARQrYdvZ2SEkJARAcdSXra0tjhw5Ijp2zJgx8PPzq/E5pbocP34cAQEBqFu3LiQSCTQ0NKqsGfH999+jVatWUFFRgaurK+Tk5P5TTeGa2GGW5hx48+YNRo8ejVmzZlXrfM+ePcOkSZNgZmYGdXV1NGrUCNOnT6/UMSD0mfT09DKpY5xPg0/eeK6JEh+ZmZno168funfvLtohPHLkCP76668y55KFwfn69esYOXIkfHx8MHXqVMTExLBBqKioCDExMTAyMsL48eMRHx+PhIQEqfkaQrsMGTIErVq1EollPHz4EH5+fujevbvomMrUKGWFioTicnJy4OXlhUGDBkn1zr569Qq9e/dGUFAQEhMTARTnzCsqKrKF8Z07d+Ds7AwDAwNIJBLMnTsX2dnZoj5cW4TihHs+ffo06tevX24ZpNjYWBgYGLAcy6KiIvj5+UFfX5+d4+nTpxgwYABatWqFqKgoVrasZHmrmnQk3LhxA8HBwVBVVYWCggIUFBTKRBCUx+nTp+Hp6QkVFRVWs3zIkCEf+I7fP+U5JstTVAeAJUuWQCKRwN/fH/Hx8Th8+LBIWf/169eQSCTYunWr6Dqy4jSqDrxuKofzbvzXHdXQ0FAoKirizz//ZH+LiYlhmgqZmZlwdHTEl19+KcpXNjU1rfI4/jGRNgYWFBRgzpw5WL58Odq1a4c+ffogKSkJv/76Kzw8PFg6R2XCX4MGDcKcOXNYCLqHhwcmTJhQpWNrEmnzz+3bt0XRi35+fujWrRuLMKhsHsnLy8OMGTPQvn17fP/998jJyUFISAimTp1abUe1rK7ZOO/OJ2k8y0KJj1mzZsHOzu4/ee0+BtnZ2Rg/fjy0tLQQGBiIb775hk1KJfO2HR0dMXbs2ErPJwxIt2/fhrOzs0jECCh2NkybNq1Cw1vWkSYUFx8fLzICS9ctTkxMhEQiYTnvBQUF6NmzJyQSCVatWsXOk5qaylQ+axvShOLmzp0LJycnUZ3uku/ntm3boKSkxD67cOECbG1tIZFIsGfPHvZ3WQwB+/XXXxEWFobo6Gh4enri5MmTSEtLQ9++fREWFlbhsUK/2LFjB8aNG8d2VXfs2IHGjRsDqD3vQ1UoKirCqVOnROFrL1++FI0D4eHhrA6z0D/c3NzQu3dvqTvwtWVH+V3gdVM5HDHvuqO6Z88e1KtXTzT2FBQUQFVVFcuWLQNQXPnDyMgIPj4+2Lp1K4KDg+Hg4CAqgSjLvHz5Ei1atGARWwJpaWkICAhAv379Kjy+vLlm27ZtaNKkSYXfqSmkGczJyckYNmwY9PT0YGhoCC8vL+zatQtAcdk9JycnxMTEsOMro7Rg2pYtW+Dv78/WaLLWJpyPxydlPMtSiY+0tDSRwSBL/PTTT4iPjwdQPDgaGBiUyZVcunQpFBUVmec1ICAAHh4emD9/PmbPno0lS5Zg2bJlFSql79mzB+bm5iIhNFn2XlZGRUJxFy9eRN26dfG///1P6oB648YNNGnSBOPHj8fDhw+xceNGlq/bv39/qderbn3FD8V/EYrbvn07NDQ0kJqaKnXRfu7cOSgpKSEoKAhfffUV3NzcsHr1aixbtqyMlkDJa9U0RUVFiI6Ohrq6epnPvvrqK7Rp04YtvKpzz69fv4aysjLbJZGV562Mhw8fYsCAARg3bpwonSMxMREDBgyAiooKLC0tYWZmhu+++040DhQVFeHFixfQ19dn4cfC+Lt9+3aoqamxaKALFy5g2LBh0NDQwMyZM2vNeMLrpnI4FfOhdlQzMjKgrq7OxK6Ea/Tv3x/u7u7MMXvs2DGEhYXB3Nwcffr0kQnDWdo7ff36dXTu3BmrV69mf3v+/DkCAwMRHh4OQNyW0dHRcHNzY+ve6swpL1++hEQikYmcbkD6xlhWVhYyMzMxbdo0SCQSdO3aFQcOHMDevXvh6uqKJk2a4NatW3j+/Dlat26NCRMmVHssFL7/5MkTtGjRQpR6yPk8+SSMZ17io+rs3r0b6urqbLfC2tpatEsmDKzZ2dmIjIxE06ZNcevWLdy5cwc9e/ZEmzZtMHjwYPj6+kJDQwNDhgzBs2fPyr3ehg0bRJOccI2aapcPJRRXWFgILS0tLFiwQKSy+fbtW7b7s2zZMpibm0NZWRlGRkbYs2dPjS/+P7RQ3OvXr1GvXr0ygl9Xrlxh79iePXvQo0cPODk5Ye3atTXeJqXJyclBUFCQSDUTAObPnw9nZ2emkC4YfKU1D6prAPv6+mLcuHHv4c7fLxWVJ9m7dy8kEgm0tbVFIiojR45E//79ER8fj/z8fKxcuRLOzs7YvXs3gH/bbNu2bdDV1cWbN2/KXEdRURFeXl4wMTFBnTp10Llz53LTAD4mvG4qh/Nh+a87qgIDBgyAu7u76L2Lj4+HRCIRpTPIslCecO9//PEHJBIJtLS0RJsXPj4+6N+/P3NeC+PEf52PhPVdTTpypTkRtmzZAjs7O5ibm+PcuXNYv349GjZsKMoxfvjwIZSUlJjjJDIyEp06dWLOgOo8k/Dd+Ph4me4nnI/DJ2E8A7zEhzSePHmCbdu2sbyPjIwMmJiYMNGEGzduoFmzZpgxYwaAst7bhIQESCQSUW1mAGxHfe7cubC1tS1ToqE0586dw969e2tsJ/VjCcVNmTIFxsbG+OWXX5hRERsbKwpdl1aPuSbyOD+mUNzw4cNhaWmJKVOm4Pbt24iLi0OvXr2Y8jxQth6zcI81jXAPenp6kEgkImGm1atXw9TUtMxEnJmZiaCgIHTv3v2dJllpKQ2ywtu3b3HkyBFW71Ng8+bN6NKlC+Tl5bFq1So2lsTGxjLnUUpKCkaMGAF5eXn4+fkB+NeRFhAQgMjISHa+zMxMFtnRr18/2NjY4Pvvv6/xnXheN5XD+e987B3VEydOQElJqczcGxAQUG6EkyzMP0eOHEGrVq1Ea7Pjx4+jX79+MDU1xYwZM5jezpdffonWrVsDELfFf52PSp+vJjlx4gS++OILKCsrw8TEBFOmTGFRSU+ePIGSkhK2bdvG+ldqaiqUlZXZen7//v1wcHBgopSy8Btzaidy9AmQkpJCvXv3pl27dtG3335Lhw4dIhcXF1JRUSEiosLCQiIiatasGbm4uNDt27fp9OnTNHfuXHJ0dCQrKyvy8fEhIiI5OTkKDg6mXbt2UU5ODhER3b9/n1avXk1t27alO3fulHsfgwcPpq+++oqaNGnygZ+4amzdupVmzJhBx44dIyKiDRs2EBHRyJEjiYhIUVGR3r59S2/evCEiInl5edHxhoaG1KxZM0pMTGR/S09Pp0aNGtGTJ0/o+vXr5OzsTMbGxhXeh6OjI/Xo0YPq1Knz3p6tMgCw/y+RSEhOTo6eP39OCxYsoPDwcFqzZg3dvXuXiIhGjx5Nly9fppSUlCqfNywsjDZt2iTqD5MmTSJPT08KCQmhPn36kLW1NQ0YMIBUVFQoNzeXiIgsLS3J0tKSiIiKiorY/Ukkkvfz4FVEuGZiYiKNGjWKOnbsSNOmTaO9e/ey9wUA7d27l6KiosjR0ZH27dtHvXr1Ijm5ssMGAFJWVqbg4GDauHEj3bhxg302Z84cGjhwIP3yyy/UqVMn6t69O2lqalK/fv3YsYqKigSAtYlwjx+bBw8ekLu7O+3evZvdw/3796lXr17k5uZGu3btori4OCIicnFxoVu3brFxRk5OjrWDs7MzPXr0iBISEoiIRM9VGQ0aNHjPT/V+yM/PJ2VlZercuTPNnz+fXrx4wT5LSkoiCwsLCgsLo82bN1N2djYREXXp0oXk5eWpZ8+erL0iIyPp1KlT9ODBA5KTk6NHjx7RrVu3yN/fn/7++2/q3r07qaqq0vz584mIaNOmTXT58mUaOHCg1L73oQHA3glhLHn16hXNmDGDunfvTg8fPiz32IKCAiosLCR7e3syNTWlnTt30oMHDyg8PJz09fVp+/btRERSn0sikRAA0tHRIR0dHbpy5QqlpaWxz4iI1NXV2T1yOLWFkmuBgoICIipeWxw5coRmzJjBxpaGDRtSdnY2FRYWUlZWFkkkEjaWtmvXjgDQb7/9Vun13N3diYhoy5Ytor//+uuv5OjoWOb7cnJyNTL/lEZHR4cSExNp2rRp9Pr1ayIiys7Opvr169OYMWMoNTWVtm3bRkRELVq0YGsaYTwpPR/99ddfRFS9+ajk+WoCABQeHk6NGjWigIAASk5OptzcXDp58iTNnz+f9PX1CQBpaWmRj48PxcTEsP61adMm0tDQIH9/fyIi6tixI6mpqdE///xDOTk57DfOzc2lpKQkevr0Kbsmh1MhNWCwv3d4iQ8xgpfw8uXL8PHxweTJk1FQUAAbGxtWe1j4jqWlJTw9PVmobUmP8IMHD9C4cWNMnToVQHGobUhICDp06AAlJSV4eHjIlCCaLAjF5eXl4ejRo5g2bRpWr15dZqdJVvjYQnFA7RBDy87ORlBQEMzMzJgq+rNnzxAUFIQff/wR48aNQ79+/fDs2TPcuXMH6urqOHToEACxEvo///wDDw8P5vGu7R5uYecjICAAmpqaaNWqlahfrFq1Cm3btkVSUhIkEomoHNm4cePg4+PDfvtTp05BSUmJlRzbsGEDJBIJlJSUUL9+fQwcOFAm8g153VQO58NQEzuqv/zyi9TcXVnZVS2PNWvWoHnz5kxT5+7du2jevDkePnyIAwcOQE9PDw8ePMCPP/4Ia2trXLlyBYA4Subs2bPw8vJi6UC1bT6aOXMmExB9+PAh7OzsmB5PSX2iX375BfLy8ggODoaWlhZ0dHSwYcMG0dpw2rRp8PLyQkJCAlJTUzFr1iwYGBigefPmrKoBh1MZMm888xIf/43IyEgEBgZi6tSpcHV1xcOHDwGAhXIvWrQIKioqolApoc1jYmIgkUjYojc7OxuLFi3CwoULcffu3Y/7IBUgK0Jx5fVVWZmca1IorjSyLGD08uVL6OrqIjIykqk8u7q6YsOGDXj06BG8vLwwZ84cpKWlwdHRkaWHlC4pFhERAU9PT5kVDqwOwvj4888/o2HDhli1ahXMzc1ZLtnKlSsxYMAAFBQUwMDAANOmTWM5/61bt8bQoUPZuYQSVXp6egCKRcX69+8vswuXz7luKofzIbh06RJUVFQwceJENsbu378fERERWL16NcLDw1l62ZIlS5jis4DwHixevBitW7fGiRMnAMjOXPs+yc/PR79+/WBpaclSAps3b86ctv7+/oiKisLSpUthY2ODM2fOlDlHYWEh+vbti/79+9d6J1xGRgbGjBkDMzOzMp9lZmbCxMQEFhYWOHz4sOgzoW+cOXMGBgYGaNSoEeTl5WFqaoqFCxfWio0xjuwg88ZzdeElPooR7lUQVZBIJGjTpg1+//130fdevHgBDw8PqKur448//mA1ly9cuID27dtj0qRJ5S7YarrmsCwJxUkTMJKl/lJTQnFCblFtY/ny5bCwsMDSpUsBAKNHj0aPHj0AFOeAGxsbIy4uDiYmJiyaQ0BoyxUrVsDHx6dKfaqmKFnLvarUq1cPP/zwA9auXYuWLVvixIkTiI6OZu/SpEmTYGpqipcvXyIzMxORkZHQ1dXFyZMnsX79enTv3h1Lly5Fz549K3TCfCx43VQO5+NTEzuqtdX5dO7cOZiamiIiIgLPnj3DoEGDMH/+fADFlT66deuGYcOGQUFBQSTYCPz7zBXN17WNgwcPQk1NjTkKSm5+RUZGijbHpEUGRUREYPr06UzsU0CW1mwc2UbmjWde4kPM69evcenSpUoXXsI9p6SkwM/PD1ZWVvD19UWDBg3g6emJo0ePsu/cunULPj4+qF+/Ptq3bw8HBwcoKiriiy++kKquLEvtwYXiysKF4v47z58/x5gxY6ClpYWUlBRs2LABPXr0YJEJoaGhmDp1KhQUFPDNN98A+LefCO+H0P61hcrea6GfBAUFoW3btsjMzMTixYvh5uaGrl27wtfXF0CxE0tOTg7Hjh0DUNzf/P390bx5c+jp6WHjxo1VivCoST7HuqkczseE76hWj927d0NDQwNr1qzB4MGDsXz5cjaG/Pjjj2yTRKj4Ut74UpvHHeHe7927Bzc3NzY+l1zDJCQkQEFBQRRpWPr4ktT0JhCndlIjKgDVESsQBIuIioUlBHGJihDEXTp27EgpKSl09uxZIvpXZMXU1JRMTU0pNTWViKhCIas6derIhHCEwNy5c2n69Ol0//59IioW8ZHWnsI96+npkZWVFWlqatK6devo2LFjpKqqSr179yYXFxfavHkz6erqUmxsLMXHx1O3bt1oxIgR9OzZM9qyZQs1b9683HPXNFwoTjqfs1Dc+6Jhw4Y0e/Zsqlu3Li1btoxu3rxJurq6lJ6eTkREUVFRlJaWRvn5+XTmzBki+ve9EP6rpKRUMzdfDZ4/f04NGzakR48eMYEqlCOWIojGREVF0Z9//knXrl2jqKgo6tChAx08eJCMjIwoJyeHTExMyNramtatW0dv374lMzMz2rp1K/3111+UkpJCgwYNorp1637Mx2QIY0JJEhMTyc/Pj9asWcP+VlRURObm5iLxPPy/eJe9vT3dvXuXLl26xL5bmvLGyC5dutCTJ0/o2rVrMjOOcjg1gby8PI0ZM4by8/MpOjqanj9/Th07dqSLFy8SUbHQZEpKCiUnJ9ONGzdIVVVVdDwAkpOTo1WrVtHmzZupXr16NfAUH48+ffqQh4cHHTp0iOLi4kRCo/369SNfX18yMjJi65DyxpfaPO4I966jo0OdO3em2NhYIhKvYVxdXUldXZ3Wr19f7vFExeO20IdqUhCNU0v5WFY6L/Hx3yiZr+Hp6cm8s1U5Zv/+/WjdujUTxCooKMC1a9cQERGB+vXrw8/PT2p5HFkp11AeXChOzOcqFPchENpp1apV8Pb2ho2NDfz9/UXtdObMGZiYmLCww9qKvb09oqOjAUgvGSYNbW1tTJ48GYWFhcjNzS1Tvmrt2rUYNmxYlc9XE3zOdVM5HFmB76hWjvBsp0+fRu/evSGRSNC9e3cA/45LtTHC679w6tQpNGnSBL/++isA8e7zhg0bsGvXrpq6Nc5nwAd1t4CX+CgDKtjZqYzCwkJycXEhNTU1unfvHhUWFtLRo0fJzc2NFi9eXOb7Qtu4ubmRnp4enTp1ioiKd9MtLCxo3bp1lJSURAcPHhSVxxHurybLNVQlOkFeXp55o4WIBE9PT7p16xadP39e9F0rKytydHSkVq1a0cGDByk4OJiIxDtRpqamZG9vT3PmzKH69evT77//Tg8fPqR169aV8XrLIsLvbWNjQ8bGxpSYmEjR0dGkrKxMPXv2JCKit2/fEhHRwIED6ezZs3Tw4EEiKu4TQpufOXOGnj59Sj169CAiImNjY3J0dKROnTrR9evX6cSJE+Tg4PCxH++jIrRlSEgIubu709WrVyk2NpZFJQAgFxcXunnzJg0ePLgmb/WdxxPhuMjISPrhhx+IqDgq4ebNm7Ry5Ur2rCUR3rP+/ftTbGwsPXr0iBQVFalTp06krKzMzvnll1/SqlWrSFFR8Z3u7UNx9OhRcnFxoYKCArZbUVhYSKGhoaSurk7Lly9nUSZGRkaUnJxMDRo0oKKiIhZB4eLiQnp6evTXX39RXl5etXctNDU1qaioiO92cDjEd1SrgvBsbm5uFBERQYqKimwOFsalOnXqlCn3+CkizDFmZmbk4OBACxcuJCKxLTB48GDq27dvjdwf5zPhQ1jkvMRH5ZTOj6wOo0ePhqGhIRo2bAgjIyMMGTKkjEhEaSZNmgRXV1ckJyeXuYd3vQ9ZggvFFfM5CMV9bJ4/fw43Nzd069ZNJgSu3gelx14FBQWMHTsWdnZ2UFZWRkhIiNR3QegTd+7cgUQiwb59+z7K/b4vuMovhyM78B1VzrtSUFCAjRs3IioqqtxcZg7nQ/FBw7Y/5xIf5dUcfvPmDUaPHs0WaFXl2bNnmDRpEszMzKCuro5GjRph+vTplToGhAEkPT1dpkMoS8OF4sRwobiaRVYmYmnK0Kmpqe+sar5z50506NABdevWhZaWFrZu3VppGTqhLRYtWiTVwJZ1eN1UDke2KCoqwrFjx1CvXj3Mnj1b6ueyMgbLCtypwOHUHP8pbgxSQpALCwtp7ty5tGLFCpo9ezbVq1ePrly5Qvv27SNbW1u6desWEVGlwl8JCQnk7+9PFy5coISEBGrbti3t3LmzSsdK42OF9OD/w2YkEgkLp7lz5w4LgWzQoAElJyfThQsXmGBZ6TYsTX5+Pq1YsYL+/vtvmjRpEj169Ig6duxIRUVFUkMrSyKEsjRu3JgUFRVrNKSHC8W9O1wormapyRBblEp/kUgkonSDhIQEGjx4MN29e7fK5/zrr79IXV2doqOjqXXr1rRkyRLKycmhfv36kYGBQYXHCm0xbtw40tbWrv4D1TCDBw8mDw8PWrJkCaWnp7PnvXTpEnXt2pXs7Oxo4cKF9Pr1a5JIJJSVlUVE/6YeERE5ODiQlpYWPX36lHJzcz/rd4PD+a9IJBLq0KED5eTk0FdffSX1c57mIKY2CnF+CKTZIRzOB+d9W+OfY4kPaV7R5ORkDBs2DHp6ejA0NISXlxcTMNi6dSucnJwQExPDjq+M0oJpW7Zsgb+/P86ePVvlc9QEXCjuv8GF4j5PpO0w5+fnY926dejVqxdGjRqF06dPo6CgAG/fvkWTJk2wcuXKKp//7du3SEhIYOkv+fn50NLSwuHDh9m/P2V43VQORzbhO6ocDkfWqbIrj5f4EAMpYmjZ2dn05s0bmj59Opmbm1NqaiqtWrWKFi1aRDk5ORQVFUW3b98mPz8/qlu3Lv39998EoErPU79+fXZdIiJfX1+6efMmXbt2jd2DrCCtbbhQHBeK41SOUD6jpGhOSkoKhYaGkoKCAi1btoz09fUpLi6OunfvTj///DMpKCiQr68vbdmyhfLz86t0HQUFBXJ1dSUFBQUiKhbf69q1K02fPp2IZGs8+RA4OjrS3Llzac+ePbRnzx6SSCRM8MzOzo4CAwMpPj6e8vPzWbSU8H4IbaOpqSn6O4fD+e/wHVUOhyPrVNl4LjmgCSG06enpdOTIEZoxYwa9ePGCiIrro2ZnZ1NhYSFlZWWRRCJhRnK7du0IAP3222/VvlF1dXV6+vQpWVlZ1WjocUmjUGiTrVu3kr29PTk6OlJycjLp6+uThoYGxcTEUNeuXalHjx4UExNDGRkZdPz4cWrYsCHZ29vT5cuX6fr160RU9ZBmoT21tLTo+++/p6CgoA/zoO9AycWl0DY///wzdejQgTQ1NenAgQPk6+tbYainvLw81alTh16+fEna2to0bNgwcnR0pKysLFq3bh2Fh4dXeA9COy5evJj27t1LTZs2lfq9j20cCMaQcH9VXXDLycmxtjQwMKCFCxdS48aNadiwYWRlZUV+fn7lHtuwYUMyNDSkBw8e0M2bN9l9FBUVsbDskvfxqRtMsgpKKKQKjosLFy5Qjx496ODBg3T16lWKi4uj6OhounbtGi1atIh27NhBlpaWzHkyaNAgOnv2rKg2d3UZNWoUeXt7E9HnsYDlKr8cDofD4XCqS5WNZ17ioxjhWU6ePEn9+/cnFRUVmj17Nvn5+dHRo0fJ0dGRunXrRjk5ORQTE8OM7cLCQqpTpw7LWfXz86MnT57Q33//TUTVW4AJz9+mTRu2cyQLCM8QFxdHgYGBpKCgQL169aLz58/TiRMn6Pz58/Tll19WuDD/4YcfyMXFhfT19Sk7O5sKCgro6NGj9NNPP5Gvr2+lzyucW09Pj+rVq1cjO8zSojSysrJozJgxNHfuXCKq+u/9/Plzmjx5Mpmbm9OmTZsoMzOThg0bRteuXaP169eThYWF1OMEY2zs2LH0xx9/kKmpKfus5PvDF/41jxCd8eTJE1qwYAHp6elR+/btKSMjg8zNzcnOzo68vb3pypUrRFTsvLS1tSUzMzNKS0ujZ8+eUdu2bcnAwIB++umnd74Pe3t7+vbbb9/XY8k0wrgwbtw4qlevHt27d49+//13Iioeq+Xl5WnevHl069YtatWqVU3eKofD4XA4HBmiylaojo4OJSYm0rRp0+j169dERJSdnU3169enMWPGUGpqKm3bto2IiFq0aMHEa4SFOgBSVlYmZ2dnevToEf31119EVD0RqZLnqwkAUHh4ODVq1IgCAgIoOTmZcnNz6eTJkzR//nzS19cnAKSlpUU+Pj4UExPDjLlNmzaRhoYG+fv7E1GxqJWamhr9888/lJOTw4yY3NxcSkpKoqdPn7JryhrSQpC5UBwXiuNUn6KiIlq+fDnZ29uTtrY2TZ48mdzc3Oj169d0/PhxMjExoWbNmpGTkxNdu3aN7t+/z5yXSUlJ5ObmRmpqakRUvFu6a9cuJnBVEmkOnc8ZXjeVw+FwOBzOu1BlS9TW1pYWLFhAO3fupD179hARkY2NDR0+fJgCAwOpR48e9P3339PDhw9JXV2dtLS06OrVq0QkNrY8PDyofv36dODAASKqXTtfEomEDAwMaO3atfT69Wv6+eefycrKitauXUtExcaO8Dzh4eEUGxtLISEh1LhxY1qzZg1FR0dTq1atqLCwkBQVFcnNzY2Sk5Pp4sWLdP/+fZo9ezZZWFhQx44d2S6TLLZPyfBGgczMTNq+fTtdvnyZTp48Sbt37yZzc3NydnYmNTU1tqsjLPxLI/SPjRs30vTp08nY2JiIiIYMGUJbtmwhItkLJS25sBZ2D2/evEnDhw8nfX196tChA3Xt2pV2795NRETBwcF0//59+ueff6p0/rp169LEiRPpjz/+oIEDB1K9evXI19eXrly5wqI8qhP+zZEt3r59S/PmzaPFixdTSEgIPXz4kAICAkhVVZVevXpFRMRymFu2bElqamr0ww8/0KZNm8jExIRu3rxJAwcOpLp16xIRUWhoKN29e5fOnTtHRETPnj2jn376iVxcXGjlypU18oyyDlf55XA4HA6HUx2qtSrgJT6IZsyYQb169SIiIhUVFfLy8mLGkbCIJSLq0KEDGRgY0MWLF2nLli2UlpZGgwcPFhme/v7+dOfOHQoICCAjIyPatm0bDR8+nK5evUpeXl4f/+GkwIXixHChOM77QlFRkcaOHUspKSk0ceJE0tHRIRcXF7p69SpduHCBiP79fa2trcnW1pZmzZpFa9asoaioKHr8+DH5+Piw85mZmVGbNm1o5syZNGjQIDI1NaWIiAgyMDAgX1/fGnnG2gTfnedwOBwOh1MZ1TKe5eXlacyYMZSfn0/R0dH0/Plz6tixI128eJGIiObMmUMpKSmUnJxMN27cIFVVVdHxAEhOTo5WrVpFmzdvpnr16r23B6kJVFRUqEOHDpSens5yl4UFmLKyMnXo0IFUVVXZwlX4THAkuLi4UMeOHSkyMpISExMpOTmZxo8fT6qqqjITKsiF4orhQnGc6lBVQ0xQOxferYCAAMrNzWVpLUKkRsOGDcnFxYWMjY1p+fLlNHLkSObIKRl9EBoaSidOnKDHjx/T1q1b6dWrVywKhFMxshbZwuFwOBwOR/aodjwaL/FRjHDvVlZWZG1tTRs3bhT9nYiof//+dOHCBbbjWnJxJnxv3bp1NGfOHDIxMaGioiKR6q4swIXiiuFCcZzqUF1DTHi3rKysyNjYmC5cuMBKugmGtZOTE+nq6tLevXuJiNg7VrIPhYeHU15eHh08eJC6du36Ph6Fw+FwOBwOh/P/vJM1wkt8/HvvOjo61LlzZ4qNjSUicU6vq6srqaur0/r168s9nujf2q5ycnIyYzQLcKE4LhTHqT7Jyck0c+ZMIqq60J3gcOnUqROlpKTQ2bNniejfscLc3JxatmxJR44coYKCAqkGuqKiYrm6AhwOh8PhcDic/0a1LRJe4kOMgoICC0vev38/EYkXy/PmzaN27dpVeA6htqsswoXiuFAcpxjByVUVMjIyaPbs2ZSTk0Py8vJM+KsiBAdR586dSU5Ojs6cOUNE/6o+169fn2xsbEhVVZXV7eZwOBwOh8PhfDwkeMctLgAUFxdH/v7+NHXq1DJKpYLhJGs7qe8TQfQpPT2dwsLC6M2bN3T69OkaDzF+3xQUFFB4eDidP3+efv/9d2rSpAnp6enRunXrqHPnzkzwzNDQkL7//nvasGEDubi4iM5RVFREISEhpKioSOvWravV+e6ZmZk0Y8YMOnjwIN24cUP02Zs3b8jBwYHq1q1L3333nUioSegXf//9NwUFBdGbN2/o1atXZGhoSBERERQREVFGJ4BTs0gbx6oq9mZlZUUREREUFRXF/paWlkZNmzYtd4wQzj106FBKTU2lhQsXkqWlJUubyMnJISUlpffzcBwOh8PhcDicavHOFh4v8fHv7mCjRo2oV69e5OTkJNVhICviX+8KF4oT8zkIxX3OSFNULywspHXr1pGdnR0dPny43GMLCgpY5MnIkSNp48aNlJWVRePHjyd9fX2Kioqq0KlYMlLj3r179ODBAyL6Nx2EG84cDofD4XA4Ncd7SY4TRJE+V+rUqUODBg0q9/NPwYkgCMVFRkaSg4ODVKG4pUuXMqE4CwsLtosmTSiutoYlC/deUijOxcWljFDcDz/8QJcuXSI7O7syQnESiYTWrVvH/lZSJO5T6Cu1FWE3uKSielxcHG3cuJFiYmLIzMyMevToQe7u7uWeQzBys7OzKT09na5fv07a2trk4eFB8+bNI39//wr7vvD79+rVizp16kQaGhrv8Qk5HA6Hw+FwOP+F92I8f86Gc0lKq4p/avTp04d27txJhw4doqtXr5KdnZ1IKC4pKYnevHnzWQnFrVy5kojKF4pbtWqV1OOJio21zyFCo7Yg/A7Jyck0a9Ysio2NpdzcXAJAU6ZModmzZ1d6jtOnT9OMGTPo7Nmz1KJFCzIwMKAOHTqInCVVQV5enhvOHA6Hw+FwODIGX7W/R0rusn5qcKE4MZ+6UNynDACp4fH79++n8PBw2r59O6WlpdGBAwfo3r171KNHD1ZqrDyE8z148IAcHR3p9OnT9L///Y/mzZtH+/btY9flcDgcDofD4dRe3lkwjPN5woXiPh+huM8JADRr1ixavnw5vXjxQvRZdHQ0xcXF0apVq8je3r5av3NGRgbp6urSkSNHyM3NjfcRDofD4XA4nFoMX8VxqgUXivt8hOI+BaT9Bjk5ORQcHEx9+vRhf5NIJKSoqEgmJiZ069YtIiJWXsrDw4OIiI4fP17t66uqqpK7uzv98ssvRPRp6B9wOBwOh8PhfK68l5xnzucJF4r79IXiajulfwMApKSkRAkJCXT//n3atWsXBQUFERGRuro6vXr1it6+fUtE/2o5uLi4kJ6eHiUkJFBeXh4pKChU6x5iYmKoQYMG7+FpOBwOh8PhcDg1CV/dc96Zz9lwLokQqs6RPR48eEDu7u60e/duIireYb5//z716tWL3NzcaOfOnRQXF0dExUbyrVu3SEVFhYiKDW8ApKysTM7OzvTo0SNKSEggoupFFXDDmcPhcDgcDufTgBvPHM5/5FMWiqvtaGpqUvPmzSk6OpqSkpKIiKh+/fqUlpZGgwYNIlNTU9q0aRM9f/6cNDQ0SE1Nja5du0ZExQay4BRp164dKSoqstBt/ntzOBwOh8PhfH5w45nD4XyyKCkp0Zo1aygrK4uWLVtGr1+/Jk1NTUpJSaGCggIaP348paWl0Zo1a6hevXpkZGTEjOyS+fuOjo5kbm5OCQkJ9OzZM248czgcDofD4XyGcOOZw+F80qirq9OkSZPo5MmTtGnTJiIqDtE+fPgwaWtr05gxY2jTpk2UmJhIGRkZrGa3YCALCtk2NjYkLy9PaWlpNfUoHA6Hw+FwOJwahBvPHA7nkyc0NJR8fX1p3rx5lJqaSlZWVkRUrKjdtWtXat26NcXFxVFqaiplZ2cT0b95zYIRPWjQIPrtt9/I1ta2Zh6Cw+FwOBwOh1OjcOOZw+F88jRs2JBmz55NdevWpWXLltHNmzdJV1eX0tPTiYgoKiqK0tLSKD8/n86cOUNE/xrNwn+VlJRq5uY5HA6Hw+FwODIBN545HM4nT1FRESkrK9O0adPo0qVLdPjwYbp37x7p6OgQEZGzszNFRkaSsbExdenShYi4KBiHw+FwOBwOR4wEvMYOh8P5THj16hUtXbqUZs+eTUREGRkZpKysTAC4sczhcDgcDofDqRD5mr4BDofD+Vioq6vTqFGj6Pjx46SlpUV5eXlExHeZORwOh8PhcDiVw3eeORzOZ4egoM3hcDgcDofD4VQVbjxzOBwOh8PhcDgcDodTCXzrhcPhcDgcDofD4XA4nErgxjOHw+FwOBwOh8PhcDiVwI1nDofD4XA4HA6Hw+FwKoEbzxwOh8PhcDgcDofD4VQCN545HA6Hw+FwOBwOh8OpBG48czgcDofD4XA4HA6HUwnceOZwOBwOh8PhcDgcDqcSuPHM4XA4HA7nP7Np0yZSV1ev6dvgcDgcDueDIQGAmr4JDofD4XA4tZucnBzKzMykxo0b1/StcDgcDofzQeDGM4fD4XA4nP9Efn4+1a1bt6Zvg8PhcDicDwoP2+ZwOBwOR8aIiYkhGxsbUlJSIk1NTerQoQNlZWUREdEPP/xAVlZWpKioSDo6OjRixAh23KtXr2jw4MGkpaVFqqqq5OXlRZcuXWKfz5w5k+zt7Wnr1q1kYGBAampqFBQURJmZmew7R44cIXd3d1JXVydNTU3q2rUr3b59m31+7949kkgktHv3bvLw8KB69erR9u3bpYZtr1mzhoyNjUlBQYHMzc1p69atH6jFOBwOh8P58HDjmcPhcDgcGeLRo0cUHBxMAwcOpMTERDpx4gT16NGDANCaNWto+PDhFBERQVeuXKH9+/eTiYkJO7Z379705MkTOnz4MJ07d44cHR3J29ubXrx4wb5z+/Zt2rdvH8XGxlJsbCydPHmSvvnmG/Z5VlYWjR07ls6ePUtxcXEkJydH3bt3p6KiItF9Tp48maKioigxMZE6depU5jl++eUXioqKonHjxtHVq1fpyy+/pPDwcPrjjz8+QKtxOBwOh/Ph4WHbHA6Hw+HIEOfPnycnJye6d+8e6evriz7T1dWl8PBwmjt3bpnj/vzzT+rSpQs9efKEFBUV2d9NTExo4sSJFBERQTNnzqSFCxfS48ePSUVFhYiIJk6cSKdOnaIzZ85IvZ9nz56RlpYWXblyhaytrenevXtkaGhIS5cupaioKPa9TZs20ejRo+nVq1dEROTm5kZWVla0fv169p0+ffpQVlYWHTx48J3bh8PhcDicmoLvPHM4HA6HI0PY2dmRt7c32djYUO/evWnDhg308uVLevLkCaWlpZG3t7fU4y5dukRv3rwhTU1NUlZWZv+7e/euKOzawMCAGc5ERDo6OvTkyRP275s3b1JwcDAZGRmRqqoqGRgYEBFRamqq6HotW7as8DkSExPJzc1N9Dc3NzdKTEysUjtwOBwOhyNryNf0DXA4HA6Hw/mXOnXq0LFjxyghIYF+++03WrFiBU2bNo3i4uIqPO7Nmzeko6NDJ06cKPNZyVzk0sJeEolEFJLt7+9P+vr6tGHDBmratCkVFRWRtbU15eXliY5r0KBB9R+Ow+FwOJxaDN955nA4HA5HxpBIJOTm5kazZs2iCxcukIKCAh07dowMDAzKNaIdHR3p8ePHJC8vTyYmJqL/NWrUqErXff78Od24cYOmT59O3t7eZGFhQS9fvnynZ7CwsKD4+HjR3+Lj48nS0vKdzsfhcDgcTk3Dd545HA6Hw5Eh/v77b4qLi6OOHTtS48aN6e+//6anT5+ShYUFzZw5kyIjI6lx48bUuXNnyszMpPj4eBo5ciR16NCBXF1dqVu3brRgwQIyMzOjtLQ0OnjwIHXv3r3SMGsiIg0NDdLU1KT169eTjo4Opaam0uTJk9/pOSZMmEB9+vQhBwcH6tChAx04cIB+/vlnOn78+Dudj8PhcDicmoYbzxwOh8PhyBCqqqp06tQpWrp0KWVkZJC+vj4tXryYOnfuTEREubm5tGTJEho/fjw1atSIevXqRUTFu9WHDh2iadOmUXh4OD19+pS0tbWpXbt21KRJkypdW05Ojnbt2kWjRo0ia2trMjc3p+XLl1P79u2r/RzdunWjZcuW0aJFiygqKooMDQ3pxx9/fKdzcTgcDocjC3C1bQ6Hw+FwOBwOh8PhcCqB5zxzOBwOh8PhcDgcDodTCdx45nA4HA6Hw+FwOBwOpxK48czhcDgcDofD4XA4HE4lcOOZw+FwOBwOh8PhcDicSuDGM4fD4XA4HA6Hw+FwOJXAjWcOh8PhcDgcDofD4XAqgRvPHA6Hw+FwOBwOh8PhVAI3njkcDofD4XA4HA6Hw6kEbjxzOBwOh8PhcDgcDodTCdx45nA4HA6Hw+FwOBwOpxK48czhcDgcDofD4XA4HE4l/B9KGzc1hGUmBwAAAABJRU5ErkJggg==", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAABKUAAAMWCAYAAAAgRDUeAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjYsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvq6yFwwAAAAlwSFlzAAAPYQAAD2EBqD+naQAAnOpJREFUeJzs3Xt8z/X///H7e5sdjG3msBnDQs5Rw5pDlNUcIkUOKSMlnw+iSVE5dhDlzMfSp9JhPklJpSKhiOWwoRzjExLfbQ7Zm2HYnr8//Pb+eLeDOez1HrtdL5f3pb2fr+fr9Xo83/Ph8bm/X+/X22aMMQIAAAAAAAAs5ObqAgAAAAAAAFD8EEoBAAAAAADAcoRSAAAAAAAAsByhFAAAAAAAACxHKAUAAAAAAADLEUoBAAAAAADAcoRSAAAAAAAAsByhFAAAAAAAACxHKAUAAAAAAADLEUoBN4hq1aqpT58+hXqOH374QTabTT/88EOhnudq7d+/XzabTfPmzXOMjR07VjabzXVFWSB7jUePHnV1KQAAAABw3RBKAS7266+/qmvXrqpataq8vb1VqVIl3XvvvZo5c6arS4PFXnvtNS1evNjVZeRq/vz5mjZtmqvLAADghjFv3jzZbDZt2rTpivfNfkMq+1GyZElVqVJFHTt21HvvvaeMjIw8912yZInatm2rsmXLytvbW7feequeffZZHTt2LMfcPn36OJ3Hz89PDRs21OTJk3M9x3PPPSebzabu3btf8ZpuVN98843Gjh3r6jKAmxahFOBC69atU+PGjbV161Y9+eSTmjVrlp544gm5ublp+vTpTnN3796tt99+20WVwgqEUgAA4FJz5szRhx9+qJkzZ+qJJ57Q8ePH9fjjj6tp06Y6ePBgjvnPPvusOnbsqOTkZD3//POaNWuWoqKiNGvWLDVs2FC7d+/OsY+Xl5c+/PBDffjhh3rttdcUGBioZ599VjExMU7zjDH6z3/+o2rVqumrr77SyZMnC23dRck333yjcePGuboM4Kbl4eoCgOLs1Vdflb+/vzZu3KiAgACnbampqU7Pvby8LKwMlzp79qw8PT3l5nbz5PinT59WyZIlXV0GAADIR9euXVWuXDnH89GjRys+Pl69e/fWww8/rJ9//tmx7T//+Y8mT56s7t27Kz4+Xu7u7o5tffr00d13362HH35YSUlJ8vD43/8N9PDw0KOPPup4/s9//lMRERFasGCBpkyZopCQEEkXb/Pw559/auXKlYqOjtaiRYtyBFc3k/T0dPn6+rq6DOCmd/P8PyzgBvTf//5X9erVyxFISVKFChWcnv/9nlLZl4SvXbtWsbGxKl++vHx9ffXggw/qyJEjTvtmZWVp7NixCgkJUcmSJXX33Xdrx44dBb5P1fr169W2bVv5+/urZMmSatWqldauXVvgde7atUvdunVT+fLl5ePjo1q1aunFF190mnPo0CE9/vjjCgoKkpeXl+rVq6d33323wOcoiNmzZ+uWW26Rj4+PmjZtqjVr1qh169Zq3bq1Y072fbU+/vhjvfTSS6pUqZJKliwpu90uSVq4cKHCw8Pl4+OjcuXK6dFHH9WhQ4cc+3/55Zey2Wz65ZdfHGOfffaZbDabHnroIad66tSp47j83WazKT09Xe+//77jEvq//25OnDihPn36KCAgQP7+/urbt69Onz592XW3bt1a9evXV2Jiou666y6VLFlSL7zwgiTpiy++UIcOHRQSEiIvLy9Vr15dL7/8sjIzM532//rrr3XgwAFHbdWqVXNsz8jI0JgxY1SjRg15eXkpNDRUzz33XL4fLciW15/Bv/9eAADARb169dITTzyh9evXa/ny5Y7xcePGqUyZMpo7d65TICVJTZs21fPPP69ff/1Vn376ab7Hd3Nzc/wbvH//fsd4fHy86tatq7vvvltRUVGKj4+/oro/+ugjRw8VGBioHj16OF3t9d5778lms+Xo/1577TXZbDZ98803jppsNpvefPNNTZ06VVWrVpWPj49atWqlbdu25TjvypUr1bJlS/n6+iogIEAPPPCAdu7c6TQn++OSO3bs0COPPKIyZcqoRYsW6tOnj2bPni1JTh9zBHD9cKUU4EJVq1ZVQkKCtm3bpvr161/VMQYPHqwyZcpozJgx2r9/v6ZNm6ZBgwZpwYIFjjkjR47UpEmT1LFjR0VHR2vr1q2Kjo7W2bNnL3v8lStXql27dgoPD9eYMWPk5uam9957T/fcc4/WrFmjpk2b5rv/L7/8opYtW6pEiRLq37+/qlWrpv/+97/66quv9Oqrr0qSUlJSdOedd8pms2nQoEEqX768vv32W/Xr1092u11Dhw69qtfmUnPmzNGgQYPUsmVLPfPMM9q/f786d+6sMmXKqHLlyjnmv/zyy/L09NSzzz6rjIwMeXp6at68eerbt6+aNGmiCRMmKCUlRdOnT9fatWu1efNmBQQEqEWLFrLZbFq9erVuu+02SdKaNWvk5uamn376yXH8I0eOaNeuXRo0aJAk6cMPP9QTTzyhpk2bqn///pKk6tWrO9XUrVs3hYWFacKECUpKStK///1vVahQQRMnTrzs+o8dO6Z27dqpR48eevTRRxUUFCTpYrhZqlQpxcbGqlSpUlq5cqVGjx4tu92uN954Q5L04osvKi0tTX/++aemTp0qSSpVqpSki4Fnp06d9NNPP6l///6qU6eOfv31V02dOlW//fZbkf04IgAAN7LHHntMc+fO1Xfffad7771Xe/bs0e7du9WnTx/5+fnluk/v3r01ZswYLVmyRD169Mj3+P/9738lSWXLlpV08Q2ozz77TMOGDZMk9ezZU3379lVycrKCg4MvW++rr76qUaNGqVu3bnriiSd05MgRzZw5U3fddZejh+rbt68WLVqk2NhY3XvvvQoNDdWvv/6qcePGqV+/fmrfvr3TMT/44AOdPHlSAwcO1NmzZzV9+nTdc889+vXXXx19zvfff6927drplltu0dixY3XmzBnNnDlTzZs3V1JSktObbJL08MMPq2bNmnrttddkjNHtt9+uw4cPa/ny5frwww8vu04AV8EAcJnvvvvOuLu7G3d3dxMZGWmee+45s2zZMnPu3Lkcc6tWrWpiYmIcz9977z0jyURFRZmsrCzH+DPPPGPc3d3NiRMnjDHGJCcnGw8PD9O5c2en440dO9ZIcjrmqlWrjCSzatUqY4wxWVlZpmbNmiY6OtrpHKdPnzZhYWHm3nvvvewa77rrLlO6dGlz4MABp/FLj9evXz9TsWJFc/ToUac5PXr0MP7+/ub06dPGGGP27dtnJJn33nvPMWfMmDHmcn+VZWRkmLJly5omTZqY8+fPO8bnzZtnJJlWrVrleA1uueUWx3mNMebcuXOmQoUKpn79+ubMmTOO8SVLlhhJZvTo0Y6xevXqmW7dujme33HHHebhhx82kszOnTuNMcYsWrTISDJbt251zPP19XX6ffx9jY8//rjT+IMPPmjKli2b79qNMaZVq1ZGkomLi8ux7dI1ZnvqqadMyZIlzdmzZx1jHTp0MFWrVs0x98MPPzRubm5mzZo1TuNxcXFGklm7dm2+tf39z/WlNV/6ewEA4EaT3att3LjxivfN/rf/yJEjuW7/66+/jCTz4IMPGmOMWbx4sZFkpk6dmu9x/fz8zB133OF4HhMTY3x9fc2RI0fMkSNHzN69e81rr71mbDabue222xzzPv30UyPJ7NmzxxhjjN1uN97e3pc9nzHG7N+/37i7u5tXX33VafzXX381Hh4eTuP/93//ZwIDA829995rMjIyzO23326qVKli0tLSHHOy+0EfHx/z559/OsbXr19vJJlnnnnGMdaoUSNToUIFc+zYMcfY1q1bjZubm+ndu7djLPv17tmzZ476Bw4ceNleE8DV4+N7gAvde++9SkhIUKdOnbR161ZNmjRJ0dHRqlSpkr788ssCHaN///5OlxG3bNlSmZmZOnDggCRpxYoVunDhgv75z3867Td48ODLHnvLli3as2ePHnnkER07dkxHjx7V0aNHlZ6erjZt2mj16tXKysrKc/8jR45o9erVevzxx1WlShWnbdk1G2P02WefqWPHjjLGOM5x9OhRRUdHKy0tTUlJSQV6LfKyadMmHTt2TE8++aTTPRR69eqlMmXK5LpPTEyMfHx8nI6Rmpqqf/7zn/L29naMd+jQQbVr19bXX3/tGGvZsqXWrFkjSTp58qS2bt2q/v37q1y5co7xNWvWKCAg4IqukBswYIDT85YtW+rYsWOOjxbmx8vLS3379s0xfukaT548qaNHj6ply5Y6ffq0du3addnjLly4UHXq1FHt2rWdfnf33HOPJGnVqlWXPQYAALgy2VcsZ99sPPu/pUuXzne/0qVL5+gb0tPTVb58eZUvX141atTQCy+8oMjISH3++eeOOfHx8WrcuLFq1KjhOE6HDh0K9BG+RYsWKSsrS926dXPqFYKDg1WzZk2nXiE4OFizZ8/W8uXL1bJlS23ZskXvvvturld/de7cWZUqVXI8b9q0qSIiIhwf8/u///s/bdmyRX369FFgYKBj3m233aZ7773XMe9Sf++1ABQ+Pr4HuFiTJk20aNEinTt3Tlu3btXnn3+uqVOnqmvXrtqyZYvq1q2b7/5/D3uyQ5a//vpLkhzhVHYTkS0wMDDPQCbbnj17JCnfm1impaXJ19dXx48fdxovX768fv/9d0nKN3g5cuSITpw4oblz52ru3Lm5zvn7Td+vVF6vgYeHR47LtrOFhYXleoxatWrlmFu7dm2nj+a1bNlS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gEI5vre3t+bPn59j/Mcff9Sff/4pLy+vHNsGDBigpKQkrVy5slBqAnD9EEoBN5BXX31V/v7+2rhxo1566SU98cQTGjdunJYtW6Z169a5urwrdvr0aVeXcFN577331Lx5c1WqVOm6H9vLy0tt2rTRf/7znxzb5s+frw4dOuS6X5cuXZSRkaGFCxde95oAAChu9u3bp3Xr1mnKlCkqX7684uPjXV2SPvroI3l4eKhjx46Fcvz27dtr4cKFunDhgtP4/PnzFR4eruDg4Bz71KlTR/Xr19e8efMKpSYA1w+hFHAD+e9//6t69eopICAgx7YKFSo4ft6/f79sNluu/xDbbDaNHTs2x/jRo0fVrVs3+fn5qWzZshoyZIjOnj3rNGf58uVq0aKFAgICVKpUKdWqVUsvvPCCJOmHH35QkyZNJEl9+/Z1XG6dXUPr1q1Vv359JSYm6q677lLJkiUd+37xxRfq0KGDQkJC5OXlperVq+vll19WZmam49ytW7fW119/rQMHDjiOXa1aNcf2jIwMjRkzRjVq1JCXl5dCQ0P13HPPKSMj47Kv66W1NWvWTD4+PgoLC1NcXFyOuampqerXr5+CgoLk7e2thg0b6v33388xLz09XcOGDVNoaKi8vLxUq1YtvfnmmzLG5FvL+fPnNW7cONWsWVPe3t4qW7asWrRooeXLl+e739mzZ7V06VJFRUXl2JZ9Cf/ChQtVt25d+fj4KDIyUr/++qsk6a233lKNGjXk7e2t1q1ba//+/bme45FHHtG3336rEydOOMY2btyoPXv26JFHHsl1nwoVKui2227TF198kW/9AADg8uLj41WmTBl16NBBXbt2LRKh1OLFixUREZHj1gHZ/dUvv/yiVq1aqWTJkqpRo4Y+/fRTSRevdIqIiJCPj49q1aql77//Ptfj9+zZU8eOHXPqhc6dO6dPP/00z/5Dku6991599dVXl+29ALgWoRRwA6lataoSExO1bdu2637sbt266ezZs5owYYLat2+vGTNmOH0MbPv27br//vuVkZGh8ePHa/LkyerUqZPjhpZ16tTR+PHjJUn9+/fXhx9+qA8//FB33XWX4xjHjh1Tu3bt1KhRI02bNk133323pIv3DChVqpRiY2M1ffp0hYeHa/To0RoxYoRj3xdffFGNGjVSuXLlHMfO/ihfVlaWOnXqpDfffFMdO3bUzJkz1blzZ02dOlXdu3cv0Pr/+usvtW/fXuHh4Zo0aZIqV66sf/zjH3r33Xcdc86cOaPWrVvrww8/VK9evfTGG2/I399fffr0cfr4pDFGnTp10tSpU9W2bVtNmTJFtWrV0vDhwxUbG5tvHWPHjtW4ceN09913a9asWXrxxRdVpUoVJSUl5btfYmKizp07pzvuuCPX7WvWrNGwYcMUExOjsWPHaufOnbr//vs1e/ZszZgxQ//85z81fPhwJSQk6PHHH8/1GA899JBsNpsWLVrkGJs/f75q166d53klKTw8/Ia8kg8AgKImPj5eDz30kDw9PdWzZ0/t2bNHGzduzHXu2bNndfTo0RyP6/llKOfPn9fGjRvz7AP++usv3X///YqIiNCkSZPk5eWlHj16aMGCBerRo4fat2+v119/Xenp6eratWuuH/evVq2aIiMjna7W/vbbb5WWlqYePXrkWVt4eLhOnDih7du3X/tCARQeA+CG8d133xl3d3fj7u5uIiMjzXPPPWeWLVtmzp075zRv3759RpJ57733chxDkhkzZozj+ZgxY4wk06lTJ6d5//znP40ks3XrVmOMMVOnTjWSzJEjR/Ksb+PGjXmet1WrVkaSiYuLy7Ht9OnTOcaeeuopU7JkSXP27FnHWIcOHUzVqlVzzP3www+Nm5ubWbNmjdN4XFyckWTWrl2bZ82X1jZ58mTHWEZGhmnUqJGpUKGC4/WdNm2akWQ++ugjx7xz586ZyMhIU6pUKWO3240xxixevNhIMq+88orTebp27WpsNpvZu3evY6xq1aomJibG8bxhw4amQ4cO+dabm3//+99Gkvn1119zbJNkvLy8zL59+xxjb731lpFkgoODHXUbY8zIkSONJKe5MTExxtfX17GGNm3aGGOMyczMNMHBwWbcuHGOP3NvvPFGjvO/9tprRpJJSUm54nUBAICLNm3aZCSZ5cuXG2OMycrKMpUrVzZDhgzJMVfSZR8bN250zM/uB/Pr83Kzd+9eI8nMnDkzx7bs/mr+/PmOsV27dhlJxs3Nzfz888+O8WXLluXoId977z1HnbNmzTKlS5d29IwPP/ywufvuu40xF3up3HqndevWGUlmwYIFV7QmANbiSingBnLvvfcqISFBnTp10tatWzVp0iRFR0erUqVK+vLLL6/p2AMHDnR6PnjwYElyfJ1u9kcGv/jiC2VlZV3VOby8vNS3b98c4z4+Po6fT548qaNHj6ply5Y6ffq0du3addnjLly4UHXq1FHt2rWd3gm85557JEmrVq267DE8PDz01FNPOZ57enrqqaeeUmpqqhITEyVdfC2Cg4PVs2dPx7wSJUro6aef1qlTp/Tjjz865rm7u+vpp592OsewYcNkjNG3336bZx0BAQHavn279uzZc9maL3Xs2DFJUpkyZXLd3qZNG6ePO2Z/Y0+XLl1UunTpHOO///57rsd55JFH9MMPPyg5OVkrV65UcnJyvpfOX1rT1X6jDwAAuHiVVFBQkONKc5vNpu7du+vjjz92uuVBtgceeEDLly/P8Rg+fPh1q+ly/UepUqWcrmaqVauWAgICVKdOHadvD7xc/9GtWzedOXNGS5Ys0cmTJ7VkyRL6D+AmQSgF3GCaNGmiRYsW6a+//tKGDRs0cuRInTx5Ul27dtWOHTuu+rg1a9Z0el69enW5ubk57i/UvXt3NW/eXE888YSCgoLUo0cPffLJJ1cUUFWqVEmenp45xrdv364HH3xQ/v7+8vPzU/ny5fXoo49KktLS0i573D179mj79u0qX7680+PWW2+VdPE+UJcTEhIiX19fp7Hs/bNfgwMHDqhmzZpyc3P+q7NOnTqO7dn/DQkJcQp7cpuXm/Hjx+vEiRO69dZb1aBBAw0fPly//PLLZevPZvK4b0KVKlWcnvv7+0uSQkNDcx3/66+/cj1O+/btVbp0aS1YsEDx8fFq0qSJatSoUaCabDbb5RcAAAByyMzM1Mcff6y7775b+/bt0969e7V3715FREQoJSVFK1asyLFP5cqVFRUVleNRt27d615fXv1H5cqVc/z77+/vf8X9R/ny5RUVFaX58+dr0aJFyszMVNeuXQtUE/0HULR5uLoAAFfH09NTTZo0UZMmTXTrrbeqb9++WrhwocaMGZPnP765vYuWl78fw8fHR6tXr9aqVav09ddfa+nSpVqwYIHuuecefffdd3J3d7/sMS+9IirbiRMn1KpVK/n5+Wn8+PGqXr26vL29lZSUpOeff75AoVdWVpYaNGigKVOm5Lr9741PUXbXXXfpv//9r7744gt99913+ve//62pU6cqLi5OTzzxRJ77lS1bVtLFZq5y5co5tuf1+8lrPK/m0svLSw899JDef/99/f7777neNP/vshvMcuXKXXYuAADIaeXKlfq///s/ffzxx/r4449zbI+Pj9d9991neV2X9h+5uV79h3Txau0nn3xSycnJateuXa5f/HMp+g/gxkAoBdwEGjduLEn6v//7P0n/u1z50m9Jk/K/QmfPnj0KCwtzPN+7d6+ysrKcPvLl5uamNm3aqE2bNpoyZYpee+01vfjii1q1apWioqKu6p2oH374QceOHdOiRYucboq+b9++HHPzOn716tW1detWtWnT5qrfDTt8+LDS09Odrpb67bffJMnxGlStWlW//PKLsrKynK6Wyv6IYdWqVR3//f7773Xy5Emnq6X+Pi8vgYGB6tu3r/r27atTp07prrvu0tixY/MNpWrXri3p4uvWoEGDgi77qjzyyCN699135ebmlu8NRrPt27dP5cqVU/ny5Qu1LgAAblbx8fGqUKGCZs+enWPbokWL9PnnnysuLi7XNwALU5UqVeTj45Nr33a9Pfjgg3rqqaf0888/a8GCBZedn11T9pXqAIomPr4H3EBWrVqV6ztI2fd9qlWrliTJz89P5cqV0+rVq53m/etf/8rz2H9vcmbOnClJateunSTp+PHjOfZp1KiRJCkjI0OSHIHO38Ow/GS/U3bpus6dO5drrb6+vrl+nK9bt246dOiQ3n777Rzbzpw5o/T09MvWceHCBb311ltONbz11lsqX768wsPDJV386FpycrJTI3ThwgXNnDlTpUqVUqtWrRzzMjMzNWvWLKdzTJ06VTabzfGa5ib73gzZSpUqpRo1ajhe47yEh4fL09NTmzZtuuxar9Xdd9+tl19+WbNmzVJwcPBl5ycmJioyMrLQ6wIA4GZ05swZLVq0SPfff7+6du2a4zFo0CCdPHnymu8vejVKlCihxo0bW9J/lCpVSnPmzNHYsWPVsWPHy85PTEyUv7+/6tWrV+i1Abh6XCkF3EAGDx6s06dP68EHH1Tt2rV17tw5rVu3TgsWLFC1atWcbiL+xBNP6PXXX9cTTzyhxo0ba/Xq1Y4rf3Kzb98+derUSW3btlVCQoI++ugjPfLII2rYsKGki/c6Wr16tTp06KCqVasqNTVV//rXv1S5cmW1aNFC0sUrlgICAhQXF6fSpUvL19dXERERTldg/V2zZs1UpkwZxcTE6Omnn5bNZtOHH36Ya/gWHh6uBQsWKDY2Vk2aNFGpUqXUsWNHPfbYY/rkk080YMAArVq1Ss2bN1dmZqZ27dqlTz75RMuWLXNcTZaXkJAQTZw4Ufv379ett96qBQsWaMuWLZo7d65KlCghSerfv7/eeust9enTR4mJiapWrZo+/fRTrV27VtOmTXNcFdWxY0fdfffdevHFF7V//341bNhQ3333nb744gsNHTpU1atXz7OOunXrqnXr1goPD1dgYKA2bdqkTz/9VIMGDcq3fm9vb9133336/vvvNX78+HznXis3Nze99NJLBZqbmpqqX375JceN9AEAQMF8+eWXOnnypDp16pTr9jvvvFPly5dXfHy8unfvfk3nmjJlikqWLOk05ubmphdeeCHPfR544AG9+OKLstvt8vPzu6bzX05MTEyB5y5fvlwdO3bknlJAUeeqr/0DcOW+/fZb8/jjj5vatWubUqVKGU9PT1OjRg0zePBgk5KS4jT39OnTpl+/fsbf39+ULl3adOvWzaSmphpJZsyYMY552V8BvGPHDtO1a1dTunRpU6ZMGTNo0CBz5swZx7wVK1aYBx54wISEhBhPT08TEhJievbsaX777Ten837xxRembt26xsPDw+mrfVu1amXq1auX67rWrl1r7rzzTuPj42NCQkLMc8895/hq4FWrVjnmnTp1yjzyyCMmICDASDJVq1Z1bDt37pyZOHGiqVevnvHy8jJlypQx4eHhZty4cSYtLS3f1zW7tk2bNpnIyEjj7e1tqlatambNmpVjbkpKiunbt68pV66c8fT0NA0aNHD6+uJsJ0+eNM8884wJCQkxJUqUMDVr1jRvvPGGycrKcppXtWpVExMT43j+yiuvmKZNm5qAgADj4+NjateubV599VVz7ty5fNdgjDGLFi0yNpvN/PHHH07jkszAgQOdxvbt22ckmTfeeMNpfNWqVUaSWbhwoWMsJibG+Pr65nvuvI43Z84cU7JkSWO32y9bPwAAyKljx47G29vbpKen5zmnT58+pkSJEubo0aPGmNz/7c/23nvvGUlm48aNjrHsfjC3h7u7e771paSkGA8PD/Phhx86jefV+1WtWtV06NAhx/jfa86tztzkdrydO3caSeb777/Pd18ArmczJp+7yQFAMdC6dWsdPXpU27Ztc3Up1yQzM1N169ZVt27d9PLLL7u6HEnS7bffrtatW2vq1KmuLgUAABSSfv366bffftOaNWtcXYokaejQoVq9erUSExO5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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "[skip] could not read /workspace/results/abm_spatial_gut_mech.csv: No columns to parse from file\n", "[info] ABM CSV not found: /workspace/results/abm_spatial_gut_mech.csv\n" ] } ], "source": [ "# === Cell 16: Robust summary plots for FBA, single-cell, and ABM outputs ===\n", "import pandas as pd, matplotlib.pyplot as plt, seaborn as sns\n", "from pathlib import Path\n", "\n", "def safe_read_csv(path):\n", " \"\"\"Return DataFrame or None if file missing/empty/invalid.\"\"\"\n", " p = Path(path)\n", " if not p.exists():\n", " print(f\"[skip] not found: {p}\")\n", " return None\n", " try:\n", " df = pd.read_csv(p)\n", " if df.empty or (len(df.columns)==0):\n", " print(f\"[skip] empty file: {p}\")\n", " return None\n", " return df\n", " except Exception as e:\n", " print(f\"[skip] could not read {p}: {e}\")\n", " return None\n", "\n", "# ---------- 1) FBA scenarios ----------\n", "candidates = [\n", " RES/\"env_scenarios_glpk_with_MazF.csv\",\n", " RES/\"fba_realistic_envs.csv\",\n", " RES/\"fba_scenarios_summary.csv\"\n", "]\n", "scen_df = next((safe_read_csv(p) for p in candidates if Path(p).exists()), None)\n", "\n", "if scen_df is not None:\n", " print(\"Loaded FBA scenario table.\")\n", " # minimal subset for readability\n", " cols_pref = [c for c in (\"env\",\"scenario\",\"label\",\"status\",\"solver\",\"growth\",\"ldopa_ex\",\"ATP_total\",\"GTP_total\") if c in scen_df.columns]\n", " display(scen_df[cols_pref].round(4).head())\n", "\n", " # ATP totals bar plot if available\n", " if \"ATP_total\" in scen_df.columns:\n", " plt.figure(figsize=(10,5))\n", " xcol = \"scenario\" if \"scenario\" in scen_df.columns else (\"label\" if \"label\" in scen_df.columns else None)\n", " if xcol is not None:\n", " sns.barplot(data=scen_df, x=xcol, y=\"ATP_total\", hue=\"env\" if \"env\" in scen_df.columns else None)\n", " plt.xticks(rotation=20, ha='right')\n", " plt.ylabel(\"ATP total (mmol gDW⁻¹ h⁻¹)\")\n", " plt.title(\"ATP budgets across scenarios\")\n", " plt.tight_layout(); plt.savefig(RES/\"ATP_budgets_scenarios.png\", dpi=150); plt.show()\n", "\n", "# ---------- 2) Single-cell dynamic (from Cell 13) ----------\n", "single_path = RES/\"single_cell_15min_mech.csv\"\n", "single_df = safe_read_csv(single_path)\n", "\n", "if single_df is not None:\n", " # harmonize column names\n", " tcol = \"t_min\" if \"t_min\" in single_df.columns else (\"time_h\" if \"time_h\" in single_df.columns else None)\n", " mucol = \"mu\" if \"mu\" in single_df.columns else (\"growth_rate\" if \"growth_rate\" in single_df.columns else None)\n", " Lcol = \"ldopa_ex\" if \"ldopa_ex\" in single_df.columns else (\"ldopa_ex_flux\" if \"ldopa_ex_flux\" in single_df.columns else None)\n", " gcol = \"glc_mM\" if \"glc_mM\" in single_df.columns else None\n", " ocol = \"o2_mM\" if \"o2_mM\" in single_df.columns else None\n", " acol = \"AHL_ext\" if \"AHL_ext\" in single_df.columns else (\"AHL_conc\" if \"AHL_conc\" in single_df.columns else None)\n", "\n", " if tcol and mucol and Lcol:\n", " fig,axs=plt.subplots(2,2,figsize=(12,8))\n", " axs[0,0].plot(single_df[tcol], single_df[mucol]); axs[0,0].set_title(\"Single-cell growth rate μ\")\n", " axs[0,1].plot(single_df[tcol], single_df[Lcol], c='brown'); axs[0,1].set_title(\"L-DOPA export\")\n", " if gcol and ocol:\n", " axs[1,0].plot(single_df[tcol], single_df[gcol], label=\"glc\"); \n", " axs[1,0].plot(single_df[tcol], single_df[ocol], label=\"o2\"); \n", " axs[1,0].legend(); axs[1,0].set_title(\"Substrate pools (mM)\")\n", " if acol:\n", " axs[1,1].plot(single_df[tcol], single_df[acol], label=\"AHL ext\"); axs[1,1].legend(); axs[1,1].set_title(\"AHL (mM)\")\n", " for ax in axs[-1,:]: ax.set_xlabel(\"time (min)\" if \"min\" in tcol else \"time (h)\")\n", " plt.tight_layout(); plt.savefig(RES/\"single_cell_panels_mech.png\", dpi=150); plt.show()\n", " else:\n", " print(\"[skip] single-cell file lacks expected columns.\")\n", "else:\n", " print(\"[info] single-cell CSV not found:\", single_path)\n", "\n", "# ---------- 3) ABM spatial (from Cell 14) ----------\n", "abm_path = RES/\"abm_spatial_gut_mech.csv\"\n", "abm_df = safe_read_csv(abm_path)\n", "\n", "if abm_df is not None:\n", " # look for time / growth columns\n", " tcol = \"t_min\" if \"t_min\" in abm_df.columns else (\"time\" if \"time\" in abm_df.columns else None)\n", " mucol = \"mu\" if \"mu\" in abm_df.columns else None\n", "\n", " if tcol and mucol:\n", " g = abm_df.groupby(tcol)[mucol].mean().reset_index()\n", " plt.figure(figsize=(7,4)); plt.plot(g[tcol], g[mucol])\n", " plt.xlabel(\"time (min)\" if \"min\" in tcol else \"time (h)\")\n", " plt.ylabel(\"⟨μ⟩ (h⁻¹)\")\n", " plt.title(\"ABM: mean growth rate over time (gut flow)\")\n", " plt.tight_layout(); plt.savefig(RES/\"abm_mu_time_gut.png\", dpi=150); plt.show()\n", " else:\n", " print(\"[skip] ABM file lacks expected columns.\")\n", "else:\n", " print(\"[info] ABM CSV not found:\", abm_path)\n" ] }, { "cell_type": "code", "execution_count": null, "id": "a94f3480-2e9b-4840-996e-3a6d09189b96", "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "id": "feaff666-c42b-4463-9894-afcbf78ccab5", "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "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.10.18" } }, "nbformat": 4, "nbformat_minor": 5 }