From b41db6c1e62697c47950e0c5bd7e1813963fc6ce Mon Sep 17 00:00:00 2001
From: pinyili2 <pinyili2@illinois.edu>
Date: Wed, 7 Aug 2024 16:55:08 -0500
Subject: [PATCH] update cadnano

---
 mrdna/readers/__init__.py                  |   2 +
 mrdna/readers/segmentmodel_from_cadnano.py |   9 +-
 mrdna/readers/test.ipynb                   | 375 +++++++++++++++------
 3 files changed, 276 insertions(+), 110 deletions(-)

diff --git a/mrdna/readers/__init__.py b/mrdna/readers/__init__.py
index 2778b41..b694be0 100644
--- a/mrdna/readers/__init__.py
+++ b/mrdna/readers/__init__.py
@@ -9,6 +9,8 @@ def read_cadnano(json_file, sequence=None, fill_sequence='T', **model_parameters
 
 def read_cadnano_input(json_file,sequence=None,**model_parameters):
     from .segmentmodel_from_cadnano import mrdna_model_from_cadnano
+    from .segmentmodel_from_lists import model_from_basepair_stack_3prime
+    
 
     return mrdna_model_from_cadnano(json_file,seq=sequence,**model_parameters)
 
diff --git a/mrdna/readers/segmentmodel_from_cadnano.py b/mrdna/readers/segmentmodel_from_cadnano.py
index 9bccb0c..ee83a3d 100644
--- a/mrdna/readers/segmentmodel_from_cadnano.py
+++ b/mrdna/readers/segmentmodel_from_cadnano.py
@@ -186,5 +186,10 @@ def mrdna_model_from_cadnano(json_file,seq=None,**model_parameters):
             seq=None
         else:
             seq=nt_prop["seq"]
-    model = model_from_basepair_stack_3prime( nt_prop["r"], nt_prop["bp"], nt_prop["stack"], nt_prop["threeprime"], seq,nt_prop["orientation"], **model_parameters )
- 
+    
+    r=np.array(list(nt_prop['r']))
+    bp=np.array(list(nt_prop['bp']))
+    three_prime=np.array((list(nt_prop["threeprime"])))
+    orientation=np.array(list(nt_prop["orientation"]))
+    model = model_from_basepair_stack_3prime( r, bp, stack, three_prime, seq, orientation, **model_parameters )
+    return model
diff --git a/mrdna/readers/test.ipynb b/mrdna/readers/test.ipynb
index 85e11c4..4a0fa13 100644
--- a/mrdna/readers/test.ipynb
+++ b/mrdna/readers/test.ipynb
@@ -2,8 +2,8 @@
  "cells": [
   {
    "cell_type": "code",
-   "execution_count": 342,
-   "id": "090f69c6",
+   "execution_count": 9,
+   "id": "d3431aaa",
    "metadata": {
     "scrolled": true
    },
@@ -11,13 +11,17 @@
    "source": [
     "import pandas as pd\n",
     "import pickle\n",
-    "import numpy as np"
+    "import numpy as np\n",
+    "import json\n",
+    "import re\n",
+    "import cadnano\n",
+    "from cadnano.document import Document\n"
    ]
   },
   {
    "cell_type": "code",
    "execution_count": 2,
-   "id": "a99e1791",
+   "id": "1b3781b0",
    "metadata": {},
    "outputs": [],
    "source": [
@@ -27,7 +31,7 @@
   {
    "cell_type": "code",
    "execution_count": 1,
-   "id": "0b58d7e9",
+   "id": "d599c577",
    "metadata": {},
    "outputs": [
     {
@@ -51,8 +55,105 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 553,
-   "id": "6033edc9",
+   "execution_count": 6,
+   "id": "7a326c43",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "def get_lattice(part):\n",
+    "    lattice_type = None\n",
+    "    _gt = part.getGridType()\n",
+    "    try:\n",
+    "        lattice_type = _gt.name.lower()\n",
+    "    except:\n",
+    "        if _gt == 1:\n",
+    "            lattice_type = 'square'\n",
+    "        elif _gt == 2:\n",
+    "            lattice_type = 'honeycomb'\n",
+    "        else:\n",
+    "            print(\"WARNING: unable to determine cadnano part lattice type\")\n",
+    "    return lattice_type\n",
+    "\n",
+    "\n",
+    "def read_json_file(filename):\n",
+    "\n",
+    "    try:\n",
+    "        with open(filename) as ch:\n",
+    "            json_data = json.load(ch)\n",
+    "    except:\n",
+    "        with open(filename) as ch:\n",
+    "            content = \"\"\n",
+    "            for l in ch:\n",
+    "                l = re.sub(r\"'\", r'\"', l)\n",
+    "                # https://stackoverflow.com/questions/4033633/handling-lazy-json-in-python-expecting-property-name\n",
+    "                # l = re.sub(r\"{\\s*(\\w)\", r'{\"\\1', l)\n",
+    "                # l = re.sub(r\",\\s*(\\w)\", r',\"\\1', l)\n",
+    "                # l = re.sub(r\"(\\w):\", r'\\1\":', l)\n",
+    "                content += l+\"\\n\"\n",
+    "            json_data = json.loads(content)\n",
+    "\n",
+    "    try:\n",
+    "        doc = Document()\n",
+    "        cadnano.fileio.v3decode.decode(doc, json_data)\n",
+    "        decoder = 3\n",
+    "    except:\n",
+    "        doc = Document()\n",
+    "        cadnano.fileio.v2decode.decode(doc, json_data)\n",
+    "        decoder = 2\n",
+    "\n",
+    "    parts = [p for p in doc.getParts()]\n",
+    "    if len(parts) != 1:\n",
+    "        raise Exception(\"Only documents containing a single cadnano part are implemented at this time.\")\n",
+    "    part = parts[0]\n",
+    "\n",
+    "    if decoder == 2:\n",
+    "        \"\"\" It seems cadnano2.5 (as of ce6ff019) does not set the EulerZ for square lattice structures correctly, doing so here \"\"\"\n",
+    "        l = get_lattice(part)\n",
+    "        if l == 'square':\n",
+    "            for id_num in part.getIdNums():\n",
+    "                if part.vh_properties.loc[id_num,'eulerZ'] == 0:\n",
+    "                    part.vh_properties.loc[id_num,'eulerZ'] = 360*(6/10.5)\n",
+    "    df=pd.DataFrame(json_data[\"vstrands\"])\n",
+    "    n_df=df.set_index(\"num\")\n",
+    "    return part,n_df\n",
+    "def get_helix_angle(part, helix_id, indices):\n",
+    "    \"\"\" Get \"start_orientation\" for helix \"\"\"\n",
+    "        # import ipdb\n",
+    "        # ipdb.set_trace()\n",
+    "\n",
+    "    \"\"\" FROM CADNANO2.5\n",
+    "    + angle is CCW\n",
+    "    - angle is CW\n",
+    "    Right handed DNA rotates clockwise from 5' to 3'\n",
+    "    we use the convention the 5' end starts at 0 degrees\n",
+    "    and it's pair is minor_groove_angle degrees away\n",
+    "    direction, hence the minus signs.  eulerZ\n",
+    "    \"\"\"\n",
+    "\n",
+    "    hp, bpr, tpr, eulerZ, mgroove = part.vh_properties.loc[helix_id,\n",
+    "                                                                    ['helical_pitch',\n",
+    "                                                                     'bases_per_repeat',\n",
+    "                                                                     'turns_per_repeat',\n",
+    "                                                                     'eulerZ',\n",
+    "                                                                     'minor_groove_angle']]\n",
+    "    twist_per_base = tpr*360./bpr\n",
+    "        # angle = eulerZ - twist_per_base*indices + 0.5*mgroove + 180\n",
+    "    angle = eulerZ + twist_per_base*indices - 0.5*mgroove\n",
+    "    return rotationAboutAxis(np.array((0,0,1)),angle)\n",
+    "\n",
+    "def nttype(scafs):\n",
+    "    def judge(i):\n",
+    "        if i ==[-1,-1,-1,-1]:\n",
+    "            return 0\n",
+    "        else: return 1\n",
+    "    n=np.array([judge(i) for i in scafs])\n",
+    "    return n\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "id": "19281ee2",
    "metadata": {},
    "outputs": [],
    "source": [
@@ -123,8 +224,8 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 555,
-   "id": "8e48e7d1",
+   "execution_count": 11,
+   "id": "77a45909",
    "metadata": {},
    "outputs": [
     {
@@ -133,67 +234,125 @@
      "text": [
       "Found cadnano version 2 file\n"
      ]
+    },
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "<ipython-input-7-d91c550125eb>:37: SettingWithCopyWarning: \n",
+      "A value is trying to be set on a copy of a slice from a DataFrame\n",
+      "\n",
+      "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n",
+      "  nt_prop[\"bp\"][bp1]=bp2\n",
+      "<ipython-input-7-d91c550125eb>:38: SettingWithCopyWarning: \n",
+      "A value is trying to be set on a copy of a slice from a DataFrame\n",
+      "\n",
+      "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n",
+      "  nt_prop[\"bp\"][bp2]=bp1\n",
+      "<ipython-input-7-d91c550125eb>:59: SettingWithCopyWarning: \n",
+      "A value is trying to be set on a copy of a slice from a DataFrame\n",
+      "\n",
+      "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n",
+      "  nt_prop[\"stack\"][stackid.index[np.where(np.array(stackid)!=-1)]]=nt_prop[\"threeprime\"][stackid.index[np.where(np.array(stackid)!=-1)]]\n"
+     ]
     }
    ],
    "source": [
-    "nt_prop=gen_prop_table(\"test/Na_liu.json\")"
+    "nt_prop=gen_prop_table(\"test/test.json\")"
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": 560,
-   "id": "4da2c91e",
+   "execution_count": 20,
+   "id": "60d832bf",
    "metadata": {},
    "outputs": [
     {
      "data": {
       "text/plain": [
-       "(array([   12,    13,    14, ..., 13920, 13921, 13922]),)"
+       "array([[[ 0.14904227, -0.98883083,  0.        ],\n",
+       "        [ 0.98883083,  0.14904227,  0.        ],\n",
+       "        [ 0.        ,  0.        ,  1.        ]],\n",
+       "\n",
+       "       [[-0.43388374, -0.90096887,  0.        ],\n",
+       "        [ 0.90096887, -0.43388374,  0.        ],\n",
+       "        [ 0.        ,  0.        ,  1.        ]],\n",
+       "\n",
+       "       [[-0.8660254 , -0.5       ,  0.        ],\n",
+       "        [ 0.5       , -0.8660254 ,  0.        ],\n",
+       "        [ 0.        ,  0.        ,  1.        ]],\n",
+       "\n",
+       "       ...,\n",
+       "\n",
+       "       [[-0.14904227, -0.98883083,  0.        ],\n",
+       "        [ 0.98883083, -0.14904227,  0.        ],\n",
+       "        [ 0.        ,  0.        ,  1.        ]],\n",
+       "\n",
+       "       [[-0.68017274, -0.73305187,  0.        ],\n",
+       "        [ 0.73305187, -0.68017274,  0.        ],\n",
+       "        [ 0.        ,  0.        ,  1.        ]],\n",
+       "\n",
+       "       [[-0.97492791, -0.22252093,  0.        ],\n",
+       "        [ 0.22252093, -0.97492791,  0.        ],\n",
+       "        [ 0.        ,  0.        ,  1.        ]]])"
       ]
      },
-     "execution_count": 560,
+     "execution_count": 20,
      "metadata": {},
      "output_type": "execute_result"
     }
    ],
    "source": [
-    "np.where(np.array(nt_prop[\"bp\"])!=-1)"
+    "np.array(list(nt_prop['orientation']))"
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": 562,
-   "id": "da512048",
+   "execution_count": 560,
+   "id": "cd1d0730",
    "metadata": {},
    "outputs": [
     {
      "data": {
       "text/plain": [
-       "vh                                                             0\n",
-       "zid                                                           21\n",
-       "is_scaf                                                     True\n",
-       "r                                [0.0, 15.75, 7.140000000000001]\n",
-       "bp                                                          7560\n",
-       "stack                                                         -1\n",
-       "threeprime                                                    13\n",
-       "seq                                                           -1\n",
-       "orientation    [[-4.440892098500626e-16, 1.0, 0.0], [-1.0, -4...\n",
-       "Name: 12, dtype: object"
+       "(array([   12,    13,    14, ..., 13920, 13921, 13922]),)"
       ]
      },
-     "execution_count": 562,
+     "execution_count": 560,
      "metadata": {},
      "output_type": "execute_result"
     }
    ],
    "source": [
-    "nt_prop.loc[12]"
+    "np.where(np.array(nt_prop[\"bp\"])!=-1)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "id": "0373e4dc",
+   "metadata": {},
+   "outputs": [
+    {
+     "ename": "NameError",
+     "evalue": "name 'nt_prop' is not defined",
+     "output_type": "error",
+     "traceback": [
+      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
+      "\u001b[0;31mNameError\u001b[0m                                 Traceback (most recent call last)",
+      "\u001b[0;32m<ipython-input-3-68f62b8d2117>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mnt_prop\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
+      "\u001b[0;31mNameError\u001b[0m: name 'nt_prop' is not defined"
+     ]
+    }
+   ],
+   "source": [
+    "nt_prop"
    ]
   },
   {
    "cell_type": "code",
    "execution_count": 468,
-   "id": "95fb0515",
+   "id": "ff612c08",
    "metadata": {},
    "outputs": [],
    "source": [
@@ -204,7 +363,7 @@
   {
    "cell_type": "code",
    "execution_count": 500,
-   "id": "dcc227ca",
+   "id": "96ffa55b",
    "metadata": {},
    "outputs": [
     {
@@ -225,7 +384,7 @@
   {
    "cell_type": "code",
    "execution_count": 498,
-   "id": "08d33dfb",
+   "id": "3ca0ce24",
    "metadata": {},
    "outputs": [
     {
@@ -247,7 +406,7 @@
   {
    "cell_type": "code",
    "execution_count": 480,
-   "id": "c2347336",
+   "id": "d11603b3",
    "metadata": {},
    "outputs": [
     {
@@ -268,7 +427,7 @@
   {
    "cell_type": "code",
    "execution_count": 549,
-   "id": "795140b5",
+   "id": "e5731ae8",
    "metadata": {},
    "outputs": [
     {
@@ -300,7 +459,7 @@
   {
    "cell_type": "code",
    "execution_count": 544,
-   "id": "f98c2927",
+   "id": "4a0bb208",
    "metadata": {},
    "outputs": [
     {
@@ -324,7 +483,7 @@
   {
    "cell_type": "code",
    "execution_count": 550,
-   "id": "56385511",
+   "id": "ea73aed6",
    "metadata": {},
    "outputs": [
     {
@@ -354,7 +513,7 @@
   {
    "cell_type": "code",
    "execution_count": 548,
-   "id": "8565bdb9",
+   "id": "033ef083",
    "metadata": {},
    "outputs": [
     {
@@ -378,7 +537,7 @@
   {
    "cell_type": "code",
    "execution_count": 527,
-   "id": "ffa55e8a",
+   "id": "284c6b7a",
    "metadata": {},
    "outputs": [
     {
@@ -403,7 +562,7 @@
   {
    "cell_type": "code",
    "execution_count": 503,
-   "id": "43a9cef8",
+   "id": "70fafb27",
    "metadata": {},
    "outputs": [
     {
@@ -429,7 +588,7 @@
   {
    "cell_type": "code",
    "execution_count": 537,
-   "id": "5d92876d",
+   "id": "08e4fe4a",
    "metadata": {},
    "outputs": [
     {
@@ -478,7 +637,7 @@
   {
    "cell_type": "code",
    "execution_count": 491,
-   "id": "6f5d2675",
+   "id": "e12ead08",
    "metadata": {},
    "outputs": [
     {
@@ -499,7 +658,7 @@
   {
    "cell_type": "code",
    "execution_count": 493,
-   "id": "15fa1dec",
+   "id": "6d7ca49f",
    "metadata": {},
    "outputs": [
     {
@@ -521,7 +680,7 @@
   {
    "cell_type": "code",
    "execution_count": 4,
-   "id": "abd8b729",
+   "id": "e9ace3af",
    "metadata": {},
    "outputs": [],
    "source": [
@@ -532,7 +691,7 @@
   {
    "cell_type": "code",
    "execution_count": null,
-   "id": "86dc559b",
+   "id": "954df4d2",
    "metadata": {},
    "outputs": [],
    "source": []
@@ -540,7 +699,7 @@
   {
    "cell_type": "code",
    "execution_count": 18,
-   "id": "b7a36513",
+   "id": "7fcb7bd0",
    "metadata": {},
    "outputs": [],
    "source": [
@@ -562,7 +721,7 @@
   {
    "cell_type": "code",
    "execution_count": 358,
-   "id": "c590e405",
+   "id": "e0d8b3ff",
    "metadata": {},
    "outputs": [
     {
@@ -591,7 +750,7 @@
   {
    "cell_type": "code",
    "execution_count": 441,
-   "id": "28e8fc5f",
+   "id": "6d351947",
    "metadata": {},
    "outputs": [
     {
@@ -774,7 +933,7 @@
   {
    "cell_type": "code",
    "execution_count": 199,
-   "id": "75798a1d",
+   "id": "a20c1429",
    "metadata": {},
    "outputs": [
     {
@@ -795,7 +954,7 @@
   {
    "cell_type": "code",
    "execution_count": 434,
-   "id": "e90bd308",
+   "id": "39b7deb4",
    "metadata": {},
    "outputs": [],
    "source": [
@@ -863,7 +1022,7 @@
   {
    "cell_type": "code",
    "execution_count": 442,
-   "id": "f1b789b7",
+   "id": "83f49b07",
    "metadata": {},
    "outputs": [
     {
@@ -908,7 +1067,7 @@
   {
    "cell_type": "code",
    "execution_count": 302,
-   "id": "15c2f5a3",
+   "id": "891a3222",
    "metadata": {},
    "outputs": [],
    "source": [
@@ -932,7 +1091,7 @@
   {
    "cell_type": "code",
    "execution_count": 368,
-   "id": "2103280f",
+   "id": "34a7d7b1",
    "metadata": {},
    "outputs": [],
    "source": [
@@ -965,7 +1124,7 @@
   {
    "cell_type": "code",
    "execution_count": 429,
-   "id": "db2d23a1",
+   "id": "ec944c23",
    "metadata": {},
    "outputs": [],
    "source": [
@@ -980,7 +1139,7 @@
   {
    "cell_type": "code",
    "execution_count": 430,
-   "id": "7a63c8bc",
+   "id": "d67c5833",
    "metadata": {},
    "outputs": [
     {
@@ -1015,7 +1174,7 @@
   {
    "cell_type": "code",
    "execution_count": 431,
-   "id": "bdf5fe8f",
+   "id": "eca06274",
    "metadata": {},
    "outputs": [
     {
@@ -1036,7 +1195,7 @@
   {
    "cell_type": "code",
    "execution_count": 433,
-   "id": "6f25d6f3",
+   "id": "1d66507f",
    "metadata": {},
    "outputs": [
     {
@@ -1057,7 +1216,7 @@
   {
    "cell_type": "code",
    "execution_count": 167,
-   "id": "75d426b5",
+   "id": "c9ea70d5",
    "metadata": {},
    "outputs": [],
    "source": [
@@ -1069,7 +1228,7 @@
   {
    "cell_type": "code",
    "execution_count": 360,
-   "id": "f7ebdd30",
+   "id": "02798620",
    "metadata": {},
    "outputs": [],
    "source": [
@@ -1079,7 +1238,7 @@
   {
    "cell_type": "code",
    "execution_count": 190,
-   "id": "eead924e",
+   "id": "c39720e6",
    "metadata": {},
    "outputs": [
     {
@@ -1262,7 +1421,7 @@
   {
    "cell_type": "code",
    "execution_count": 200,
-   "id": "71493bd1",
+   "id": "81cd15ec",
    "metadata": {},
    "outputs": [],
    "source": [
@@ -1298,7 +1457,7 @@
   {
    "cell_type": "code",
    "execution_count": 201,
-   "id": "3622ebc9",
+   "id": "719a89e5",
    "metadata": {},
    "outputs": [
     {
@@ -1321,7 +1480,7 @@
   {
    "cell_type": "code",
    "execution_count": 146,
-   "id": "74c4ae5a",
+   "id": "a8470ece",
    "metadata": {},
    "outputs": [],
    "source": [
@@ -1331,7 +1490,7 @@
   {
    "cell_type": "code",
    "execution_count": 148,
-   "id": "e6dc1404",
+   "id": "2ec8d095",
    "metadata": {},
    "outputs": [
     {
@@ -1364,7 +1523,7 @@
   {
    "cell_type": "code",
    "execution_count": 137,
-   "id": "59fac010",
+   "id": "ab361dd6",
    "metadata": {},
    "outputs": [],
    "source": [
@@ -1381,7 +1540,7 @@
   {
    "cell_type": "code",
    "execution_count": null,
-   "id": "d42bb41e",
+   "id": "f3ecd95f",
    "metadata": {},
    "outputs": [],
    "source": []
@@ -1389,7 +1548,7 @@
   {
    "cell_type": "code",
    "execution_count": 84,
-   "id": "c73af530",
+   "id": "256fccfe",
    "metadata": {},
    "outputs": [],
    "source": [
@@ -1400,7 +1559,7 @@
   {
    "cell_type": "code",
    "execution_count": 156,
-   "id": "0b16d613",
+   "id": "1ac95587",
    "metadata": {},
    "outputs": [
     {
@@ -1526,7 +1685,7 @@
   {
    "cell_type": "code",
    "execution_count": 157,
-   "id": "90f57ab5",
+   "id": "c016cb03",
    "metadata": {},
    "outputs": [
     {
@@ -1643,7 +1802,7 @@
   {
    "cell_type": "code",
    "execution_count": 128,
-   "id": "fac146fd",
+   "id": "11e1b98e",
    "metadata": {},
    "outputs": [
     {
@@ -1665,7 +1824,7 @@
   {
    "cell_type": "code",
    "execution_count": 127,
-   "id": "baf83a53",
+   "id": "5a46d99d",
    "metadata": {},
    "outputs": [
     {
@@ -1785,7 +1944,7 @@
   {
    "cell_type": "code",
    "execution_count": 100,
-   "id": "42d9c84a",
+   "id": "f6549e2c",
    "metadata": {},
    "outputs": [
     {
@@ -1810,7 +1969,7 @@
   {
    "cell_type": "code",
    "execution_count": 13,
-   "id": "9cbfe156",
+   "id": "24b98917",
    "metadata": {},
    "outputs": [
     {
@@ -1831,7 +1990,7 @@
   {
    "cell_type": "code",
    "execution_count": 14,
-   "id": "5c918abe",
+   "id": "71923b7f",
    "metadata": {},
    "outputs": [
     {
@@ -1853,7 +2012,7 @@
   {
    "cell_type": "code",
    "execution_count": 198,
-   "id": "eae94886",
+   "id": "1307361f",
    "metadata": {},
    "outputs": [
     {
@@ -1875,7 +2034,7 @@
   {
    "cell_type": "code",
    "execution_count": 15,
-   "id": "8fc2335a",
+   "id": "3772e934",
    "metadata": {},
    "outputs": [
     {
@@ -1896,7 +2055,7 @@
   {
    "cell_type": "code",
    "execution_count": 173,
-   "id": "715d6b94",
+   "id": "5c1f341d",
    "metadata": {},
    "outputs": [],
    "source": [
@@ -1932,7 +2091,7 @@
   {
    "cell_type": "code",
    "execution_count": 177,
-   "id": "327e0a5e",
+   "id": "495b9e03",
    "metadata": {},
    "outputs": [],
    "source": [
@@ -1968,7 +2127,7 @@
   {
    "cell_type": "code",
    "execution_count": 187,
-   "id": "f31089a3",
+   "id": "c70f83b0",
    "metadata": {},
    "outputs": [
     {
@@ -2195,7 +2354,7 @@
   {
    "cell_type": "code",
    "execution_count": 142,
-   "id": "fede9c99",
+   "id": "df50d6fb",
    "metadata": {},
    "outputs": [],
    "source": [
@@ -2232,7 +2391,7 @@
   {
    "cell_type": "code",
    "execution_count": 117,
-   "id": "b0272fe0",
+   "id": "f6f7acb5",
    "metadata": {},
    "outputs": [],
    "source": [
@@ -2253,7 +2412,7 @@
   {
    "cell_type": "code",
    "execution_count": 116,
-   "id": "ad669f8a",
+   "id": "8afcf746",
    "metadata": {},
    "outputs": [
     {
@@ -2465,7 +2624,7 @@
   {
    "cell_type": "code",
    "execution_count": 157,
-   "id": "95284143",
+   "id": "2132b521",
    "metadata": {},
    "outputs": [
     {
@@ -2489,7 +2648,7 @@
   {
    "cell_type": "code",
    "execution_count": 152,
-   "id": "1e445750",
+   "id": "539a2be6",
    "metadata": {},
    "outputs": [
     {
@@ -2510,7 +2669,7 @@
   {
    "cell_type": "code",
    "execution_count": 62,
-   "id": "9768df8d",
+   "id": "ba5ab701",
    "metadata": {},
    "outputs": [
     {
@@ -2738,7 +2897,7 @@
   {
    "cell_type": "code",
    "execution_count": 3,
-   "id": "583c116a",
+   "id": "0e988589",
    "metadata": {},
    "outputs": [],
    "source": [
@@ -2864,7 +3023,7 @@
   {
    "cell_type": "code",
    "execution_count": 4,
-   "id": "1f10069b",
+   "id": "821ca309",
    "metadata": {},
    "outputs": [],
    "source": [
@@ -2885,7 +3044,7 @@
   {
    "cell_type": "code",
    "execution_count": 20,
-   "id": "465ae2a5",
+   "id": "870c2661",
    "metadata": {},
    "outputs": [
     {
@@ -2947,7 +3106,7 @@
   {
    "cell_type": "code",
    "execution_count": 25,
-   "id": "81d0004d",
+   "id": "a6cb689d",
    "metadata": {},
    "outputs": [
     {
@@ -3009,7 +3168,7 @@
   {
    "cell_type": "code",
    "execution_count": null,
-   "id": "91dc0c7f",
+   "id": "dd799008",
    "metadata": {},
    "outputs": [],
    "source": [
@@ -3022,7 +3181,7 @@
   {
    "cell_type": "code",
    "execution_count": 13,
-   "id": "e884018f",
+   "id": "df97d32a",
    "metadata": {},
    "outputs": [
     {
@@ -3043,7 +3202,7 @@
   {
    "cell_type": "code",
    "execution_count": 7,
-   "id": "eef6f08c",
+   "id": "191c7b94",
    "metadata": {},
    "outputs": [
     {
@@ -3092,7 +3251,7 @@
   {
    "cell_type": "code",
    "execution_count": 36,
-   "id": "6a4b7695",
+   "id": "d1fb1c97",
    "metadata": {},
    "outputs": [
     {
@@ -3154,7 +3313,7 @@
   {
    "cell_type": "code",
    "execution_count": 1,
-   "id": "30cde48b",
+   "id": "aa4f5ed8",
    "metadata": {},
    "outputs": [
     {
@@ -3180,7 +3339,7 @@
   {
    "cell_type": "code",
    "execution_count": null,
-   "id": "f05ebf5f",
+   "id": "cb9366dd",
    "metadata": {},
    "outputs": [],
    "source": []
@@ -3188,7 +3347,7 @@
   {
    "cell_type": "code",
    "execution_count": 3,
-   "id": "2bd820af",
+   "id": "2d779081",
    "metadata": {},
    "outputs": [
     {
@@ -3208,7 +3367,7 @@
   {
    "cell_type": "code",
    "execution_count": 13,
-   "id": "394c44c5",
+   "id": "ad471f3d",
    "metadata": {},
    "outputs": [
     {
@@ -3229,7 +3388,7 @@
   {
    "cell_type": "code",
    "execution_count": 15,
-   "id": "12c3ce83",
+   "id": "9d66b3aa",
    "metadata": {},
    "outputs": [
     {
@@ -3299,7 +3458,7 @@
   {
    "cell_type": "code",
    "execution_count": 16,
-   "id": "11a55f6c",
+   "id": "50447f7e",
    "metadata": {},
    "outputs": [],
    "source": [
@@ -3310,7 +3469,7 @@
   {
    "cell_type": "code",
    "execution_count": 26,
-   "id": "07e5d147",
+   "id": "145493e6",
    "metadata": {},
    "outputs": [
     {
@@ -3419,7 +3578,7 @@
   {
    "cell_type": "code",
    "execution_count": 25,
-   "id": "123e2f5e",
+   "id": "bda26a99",
    "metadata": {},
    "outputs": [
     {
@@ -3440,7 +3599,7 @@
   {
    "cell_type": "code",
    "execution_count": 10,
-   "id": "670a0bc5",
+   "id": "21c76d05",
    "metadata": {},
    "outputs": [
     {
@@ -3471,7 +3630,7 @@
   {
    "cell_type": "code",
    "execution_count": 1,
-   "id": "bcb8f7cc",
+   "id": "49dad459",
    "metadata": {},
    "outputs": [
     {
@@ -3968,7 +4127,7 @@
   {
    "cell_type": "code",
    "execution_count": 3,
-   "id": "1b177c60",
+   "id": "7badd9d8",
    "metadata": {},
    "outputs": [
     {
@@ -4002,7 +4161,7 @@
   {
    "cell_type": "code",
    "execution_count": 4,
-   "id": "677c2d67",
+   "id": "a1ba34df",
    "metadata": {},
    "outputs": [
     {
@@ -4022,7 +4181,7 @@
   {
    "cell_type": "code",
    "execution_count": 5,
-   "id": "7e7ba0e1",
+   "id": "e7309034",
    "metadata": {},
    "outputs": [],
    "source": [
@@ -4032,7 +4191,7 @@
   {
    "cell_type": "code",
    "execution_count": 6,
-   "id": "52014792",
+   "id": "705faaff",
    "metadata": {},
    "outputs": [
     {
@@ -4053,7 +4212,7 @@
   {
    "cell_type": "code",
    "execution_count": 7,
-   "id": "8b1b263b",
+   "id": "75417690",
    "metadata": {},
    "outputs": [
     {
@@ -4080,7 +4239,7 @@
   {
    "cell_type": "code",
    "execution_count": null,
-   "id": "abb6ad51",
+   "id": "8ca5d402",
    "metadata": {},
    "outputs": [],
    "source": []
-- 
GitLab