{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "0e44c6d0-5725-4b47-bf3a-86ed49a583c7",
   "metadata": {},
   "source": [
    "# Assignments \n",
    "\n",
    "Under some conditions, one might want a meta-species amount to be a function of other species. A more classic example lies in expressing the concentration of a species using the amount of free ligands from a hill function. For those cases, MobsPy assignments are the solution. \n",
    "\n",
    "There are two available notations for assignments. The first one lies in using the \"assign\" keyword with the dot operator accompanied by parenthesis. Inside the parenthesis, the user can write an operation with the meta-species that will define the assignment.\n",
    "The expression must be written inside the context of the parenthesis, as outside the parenthesis, the sum of two meta-species is used for reactions, and the product is used to create new meta-species. \n",
    "\n",
    "As an example, we assign the value of a meta-species A according to a hill function with ligand L. \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "6342bad7-ee85-498a-9778-2c543b443c79",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Compiling model\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Species\n",
      "A,0\n",
      "L,0\n",
      "\n",
      "Mappings\n",
      "A :\n",
      "A\n",
      "L :\n",
      "L\n",
      "\n",
      "Parameters\n",
      "volume,1\n",
      "\n",
      "Reactions\n",
      "\n",
      "Assignments\n",
      "assignment_0,{'species': 'A', 'expression': '(((L)^2)/(((L)^2)+100))'}\n",
      "\n"
     ]
    }
   ],
   "source": [
    "from mobspy import *\n",
    "\n",
    "A, L = BaseSpecies()\n",
    "\n",
    "A.assign(L**2/(L**2 + 100))\n",
    "\n",
    "S = Simulation(A | L)\n",
    "print(S.compile())"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "50297f79-e643-4968-8fca-10f2cca1b875",
   "metadata": {},
   "source": [
    "The other assignment notation uses the Assign context with Python's native \"with\". Inside the Assign context, operations between meta-species follow the same rules when inside the parenthesis of the \"assign\" using the dot operator.  \n",
    "One can then assign this operation to meta-species using the call operator inside the context. \n",
    "Below, we rewrite this section's first example using the alternative syntax. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "74f390fe-b828-4d46-95ec-158ec4a414ff",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Compiling model\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Species\n",
      "A,0\n",
      "L,0\n",
      "\n",
      "Mappings\n",
      "A :\n",
      "A\n",
      "L :\n",
      "L\n",
      "\n",
      "Parameters\n",
      "volume,1\n",
      "\n",
      "Reactions\n",
      "\n",
      "Assignments\n",
      "assignment_0,{'species': 'A', 'expression': '(((L)^2)/(((L)^2)+100))'}\n",
      "\n"
     ]
    }
   ],
   "source": [
    "from mobspy import *\n",
    "\n",
    "A, L = BaseSpecies()\n",
    "\n",
    "with Assign:\n",
    "    r = L**2/(L**2 + 100)\n",
    "    A(r)\n",
    "\n",
    "S = Simulation(A | L)\n",
    "print(S.compile())"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "875f12c6-76e7-4726-947a-6d97a464cf4c",
   "metadata": {},
   "source": [
    "Different from other meta-species, assignments are not consumed when engaging in reactions. \n",
    "Their amount is only dictated by the operation assigned to them.\n",
    "It can be better seen in the example below, where A is in a reaction that indicates it would be consumed to produce P. However, it remains constant as it was assigned to be the value of 1."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "4d52afbc-a46b-4998-bd3b-4611d30156a5",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Compiling model\n",
      "Starting Simulator\n",
      "Simulation is Over\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 10788 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "from mobspy import *\n",
    "\n",
    "A, P = BaseSpecies()\n",
    "\n",
    "A.assign(1)\n",
    "\n",
    "A >> P [1]\n",
    "\n",
    "S = Simulation(A | P)\n",
    "S.duration = 10\n",
    "S.run()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e00136ed-4953-4827-b0dd-ea52a862c685",
   "metadata": {},
   "source": [
    "Meta-species can also have substates as assigned an expression by using the dot operator query. Similarly to initial values, the characteristic spaces not specified in the query will be replaced by the default of that respective inheritor. To perform the assignment of a specific state, one must query first for the characteristics and then follow with the assigned keyword. \n",
    "\n",
    "Furthermore, dot operator queries can be performed for meta-species in the operation itself. When a meta-species is used to construct an operation for an assignment, the sum of the amounts of all states will be considered. The query allows one to specify the sum of some states.\n",
    "\n",
    "Below, we supply an example for visualization. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "34a015fb-057a-47a7-a617-3bdb29cad5a1",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Compiling model\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Species\n",
      "A.a1,0\n",
      "A.a2,0\n",
      "B.b1,0\n",
      "B.b2,0\n",
      "B.b3,0\n",
      "\n",
      "Mappings\n",
      "A :\n",
      "A.a1\n",
      "A.a2\n",
      "B :\n",
      "B.b1\n",
      "B.b2\n",
      "B.b3\n",
      "\n",
      "Parameters\n",
      "volume,1\n",
      "\n",
      "Reactions\n",
      "\n",
      "Assignments\n",
      "assignment_0,{'species': 'A.a1', 'expression': '((B.b1+B.b2+B.b3)^2)'}\n",
      "assignment_1,{'species': 'A.a2', 'expression': '((B.b1)^2)'}\n",
      "\n"
     ]
    }
   ],
   "source": [
    "from mobspy import *\n",
    "\n",
    "A, B = BaseSpecies()\n",
    "A.a1, A.a2, B.b1, B.b2, B.b3\n",
    "\n",
    "A.a1.assign(B**2)\n",
    "A.a2.assign(B.b1**2)\n",
    "\n",
    "S = Simulation(A | B)\n",
    "print(S.compile())"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b0e70169-74d4-48a1-9824-57fbc31576c3",
   "metadata": {},
   "source": [
    "Assignments are compatible with units, and consistency between unit operations is checked. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a330d994-c99f-4c21-bd9f-7e0b7c0285b4",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
