diff --git "a/notebooks/protac_degradation_predictor.ipynb" "b/notebooks/protac_degradation_predictor.ipynb" --- "a/notebooks/protac_degradation_predictor.ipynb" +++ "b/notebooks/protac_degradation_predictor.ipynb" @@ -539,7 +539,46 @@ "cell_type": "code", "execution_count": 9, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Downloading embeddings from https://ftp.uniprot.org/pub/databases/uniprot/current_release/knowledgebase/embeddings/UP000005640_9606/per-protein.h5\n" + ] + }, + { + "ename": "URLError", + "evalue": "", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mSSLCertVerificationError\u001b[0m Traceback (most recent call last)", + "File \u001b[0;32m/opt/conda/lib/python3.10/urllib/request.py:1348\u001b[0m, in \u001b[0;36mAbstractHTTPHandler.do_open\u001b[0;34m(self, http_class, req, **http_conn_args)\u001b[0m\n\u001b[1;32m 1347\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m-> 1348\u001b[0m \u001b[43mh\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mrequest\u001b[49m\u001b[43m(\u001b[49m\u001b[43mreq\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mget_method\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mreq\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mselector\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mreq\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mdata\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mheaders\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 1349\u001b[0m \u001b[43m \u001b[49m\u001b[43mencode_chunked\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mreq\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mhas_header\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;124;43mTransfer-encoding\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 1350\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mOSError\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m err: \u001b[38;5;66;03m# timeout error\u001b[39;00m\n", + "File \u001b[0;32m/opt/conda/lib/python3.10/http/client.py:1282\u001b[0m, in \u001b[0;36mHTTPConnection.request\u001b[0;34m(self, method, url, body, headers, encode_chunked)\u001b[0m\n\u001b[1;32m 1281\u001b[0m \u001b[38;5;250m\u001b[39m\u001b[38;5;124;03m\"\"\"Send a complete request to the server.\"\"\"\u001b[39;00m\n\u001b[0;32m-> 1282\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_send_request\u001b[49m\u001b[43m(\u001b[49m\u001b[43mmethod\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43murl\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mbody\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mheaders\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mencode_chunked\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[0;32m/opt/conda/lib/python3.10/http/client.py:1328\u001b[0m, in \u001b[0;36mHTTPConnection._send_request\u001b[0;34m(self, method, url, body, headers, encode_chunked)\u001b[0m\n\u001b[1;32m 1327\u001b[0m body \u001b[38;5;241m=\u001b[39m _encode(body, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mbody\u001b[39m\u001b[38;5;124m'\u001b[39m)\n\u001b[0;32m-> 1328\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mendheaders\u001b[49m\u001b[43m(\u001b[49m\u001b[43mbody\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mencode_chunked\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mencode_chunked\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[0;32m/opt/conda/lib/python3.10/http/client.py:1277\u001b[0m, in \u001b[0;36mHTTPConnection.endheaders\u001b[0;34m(self, message_body, encode_chunked)\u001b[0m\n\u001b[1;32m 1276\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m CannotSendHeader()\n\u001b[0;32m-> 1277\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_send_output\u001b[49m\u001b[43m(\u001b[49m\u001b[43mmessage_body\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mencode_chunked\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mencode_chunked\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[0;32m/opt/conda/lib/python3.10/http/client.py:1037\u001b[0m, in \u001b[0;36mHTTPConnection._send_output\u001b[0;34m(self, message_body, encode_chunked)\u001b[0m\n\u001b[1;32m 1036\u001b[0m \u001b[38;5;28;01mdel\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_buffer[:]\n\u001b[0;32m-> 1037\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43msend\u001b[49m\u001b[43m(\u001b[49m\u001b[43mmsg\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 1039\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m message_body \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[1;32m 1040\u001b[0m \n\u001b[1;32m 1041\u001b[0m \u001b[38;5;66;03m# create a consistent interface to message_body\u001b[39;00m\n", + "File \u001b[0;32m/opt/conda/lib/python3.10/http/client.py:975\u001b[0m, in \u001b[0;36mHTTPConnection.send\u001b[0;34m(self, data)\u001b[0m\n\u001b[1;32m 974\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mauto_open:\n\u001b[0;32m--> 975\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mconnect\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 976\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n", + "File \u001b[0;32m/opt/conda/lib/python3.10/http/client.py:1454\u001b[0m, in \u001b[0;36mHTTPSConnection.connect\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 1452\u001b[0m server_hostname \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mhost\n\u001b[0;32m-> 1454\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39msock \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_context\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mwrap_socket\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43msock\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 1455\u001b[0m \u001b[43m \u001b[49m\u001b[43mserver_hostname\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mserver_hostname\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[0;32m/opt/conda/lib/python3.10/ssl.py:513\u001b[0m, in \u001b[0;36mSSLContext.wrap_socket\u001b[0;34m(self, sock, server_side, do_handshake_on_connect, suppress_ragged_eofs, server_hostname, session)\u001b[0m\n\u001b[1;32m 507\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mwrap_socket\u001b[39m(\u001b[38;5;28mself\u001b[39m, sock, server_side\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mFalse\u001b[39;00m,\n\u001b[1;32m 508\u001b[0m do_handshake_on_connect\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mTrue\u001b[39;00m,\n\u001b[1;32m 509\u001b[0m suppress_ragged_eofs\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mTrue\u001b[39;00m,\n\u001b[1;32m 510\u001b[0m server_hostname\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mNone\u001b[39;00m, session\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mNone\u001b[39;00m):\n\u001b[1;32m 511\u001b[0m \u001b[38;5;66;03m# SSLSocket class handles server_hostname encoding before it calls\u001b[39;00m\n\u001b[1;32m 512\u001b[0m \u001b[38;5;66;03m# ctx._wrap_socket()\u001b[39;00m\n\u001b[0;32m--> 513\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43msslsocket_class\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_create\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 514\u001b[0m \u001b[43m \u001b[49m\u001b[43msock\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43msock\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 515\u001b[0m \u001b[43m \u001b[49m\u001b[43mserver_side\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mserver_side\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 516\u001b[0m \u001b[43m \u001b[49m\u001b[43mdo_handshake_on_connect\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mdo_handshake_on_connect\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 517\u001b[0m \u001b[43m \u001b[49m\u001b[43msuppress_ragged_eofs\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43msuppress_ragged_eofs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 518\u001b[0m \u001b[43m \u001b[49m\u001b[43mserver_hostname\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mserver_hostname\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 519\u001b[0m \u001b[43m \u001b[49m\u001b[43mcontext\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[1;32m 520\u001b[0m \u001b[43m \u001b[49m\u001b[43msession\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43msession\u001b[49m\n\u001b[1;32m 521\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[0;32m/opt/conda/lib/python3.10/ssl.py:1071\u001b[0m, in \u001b[0;36mSSLSocket._create\u001b[0;34m(cls, sock, server_side, do_handshake_on_connect, suppress_ragged_eofs, server_hostname, context, session)\u001b[0m\n\u001b[1;32m 1070\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mdo_handshake_on_connect should not be specified for non-blocking sockets\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m-> 1071\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mdo_handshake\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 1072\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m (\u001b[38;5;167;01mOSError\u001b[39;00m, \u001b[38;5;167;01mValueError\u001b[39;00m):\n", + "File \u001b[0;32m/opt/conda/lib/python3.10/ssl.py:1342\u001b[0m, in \u001b[0;36mSSLSocket.do_handshake\u001b[0;34m(self, block)\u001b[0m\n\u001b[1;32m 1341\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39msettimeout(\u001b[38;5;28;01mNone\u001b[39;00m)\n\u001b[0;32m-> 1342\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_sslobj\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mdo_handshake\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 1343\u001b[0m \u001b[38;5;28;01mfinally\u001b[39;00m:\n", + "\u001b[0;31mSSLCertVerificationError\u001b[0m: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self signed certificate in certificate chain (_ssl.c:997)", + "\nDuring handling of the above exception, another exception occurred:\n", + "\u001b[0;31mURLError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[9], line 9\u001b[0m\n\u001b[1;32m 6\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m os\u001b[38;5;241m.\u001b[39mpath\u001b[38;5;241m.\u001b[39mexists(embeddings_path):\n\u001b[1;32m 7\u001b[0m \u001b[38;5;66;03m# Download the file\u001b[39;00m\n\u001b[1;32m 8\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mDownloading embeddings from \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mdownload_link\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m'\u001b[39m)\n\u001b[0;32m----> 9\u001b[0m \u001b[43murllib\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mrequest\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43murlretrieve\u001b[49m\u001b[43m(\u001b[49m\u001b[43mdownload_link\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43membeddings_path\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[0;32m/opt/conda/lib/python3.10/urllib/request.py:241\u001b[0m, in \u001b[0;36murlretrieve\u001b[0;34m(url, filename, reporthook, data)\u001b[0m\n\u001b[1;32m 224\u001b[0m \u001b[38;5;250m\u001b[39m\u001b[38;5;124;03m\"\"\"\u001b[39;00m\n\u001b[1;32m 225\u001b[0m \u001b[38;5;124;03mRetrieve a URL into a temporary location on disk.\u001b[39;00m\n\u001b[1;32m 226\u001b[0m \n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 237\u001b[0m \u001b[38;5;124;03mdata file as well as the resulting HTTPMessage object.\u001b[39;00m\n\u001b[1;32m 238\u001b[0m \u001b[38;5;124;03m\"\"\"\u001b[39;00m\n\u001b[1;32m 239\u001b[0m url_type, path \u001b[38;5;241m=\u001b[39m _splittype(url)\n\u001b[0;32m--> 241\u001b[0m \u001b[38;5;28;01mwith\u001b[39;00m contextlib\u001b[38;5;241m.\u001b[39mclosing(\u001b[43murlopen\u001b[49m\u001b[43m(\u001b[49m\u001b[43murl\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mdata\u001b[49m\u001b[43m)\u001b[49m) \u001b[38;5;28;01mas\u001b[39;00m fp:\n\u001b[1;32m 242\u001b[0m headers \u001b[38;5;241m=\u001b[39m fp\u001b[38;5;241m.\u001b[39minfo()\n\u001b[1;32m 244\u001b[0m \u001b[38;5;66;03m# Just return the local path and the \"headers\" for file://\u001b[39;00m\n\u001b[1;32m 245\u001b[0m \u001b[38;5;66;03m# URLs. No sense in performing a copy unless requested.\u001b[39;00m\n", + "File \u001b[0;32m/opt/conda/lib/python3.10/urllib/request.py:216\u001b[0m, in \u001b[0;36murlopen\u001b[0;34m(url, data, timeout, cafile, capath, cadefault, context)\u001b[0m\n\u001b[1;32m 214\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m 215\u001b[0m opener \u001b[38;5;241m=\u001b[39m _opener\n\u001b[0;32m--> 216\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mopener\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mopen\u001b[49m\u001b[43m(\u001b[49m\u001b[43murl\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mdata\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mtimeout\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[0;32m/opt/conda/lib/python3.10/urllib/request.py:519\u001b[0m, in \u001b[0;36mOpenerDirector.open\u001b[0;34m(self, fullurl, data, timeout)\u001b[0m\n\u001b[1;32m 516\u001b[0m req \u001b[38;5;241m=\u001b[39m meth(req)\n\u001b[1;32m 518\u001b[0m sys\u001b[38;5;241m.\u001b[39maudit(\u001b[38;5;124m'\u001b[39m\u001b[38;5;124murllib.Request\u001b[39m\u001b[38;5;124m'\u001b[39m, req\u001b[38;5;241m.\u001b[39mfull_url, req\u001b[38;5;241m.\u001b[39mdata, req\u001b[38;5;241m.\u001b[39mheaders, req\u001b[38;5;241m.\u001b[39mget_method())\n\u001b[0;32m--> 519\u001b[0m response \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_open\u001b[49m\u001b[43m(\u001b[49m\u001b[43mreq\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mdata\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 521\u001b[0m \u001b[38;5;66;03m# post-process response\u001b[39;00m\n\u001b[1;32m 522\u001b[0m meth_name \u001b[38;5;241m=\u001b[39m protocol\u001b[38;5;241m+\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m_response\u001b[39m\u001b[38;5;124m\"\u001b[39m\n", + "File \u001b[0;32m/opt/conda/lib/python3.10/urllib/request.py:536\u001b[0m, in \u001b[0;36mOpenerDirector._open\u001b[0;34m(self, req, data)\u001b[0m\n\u001b[1;32m 533\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m result\n\u001b[1;32m 535\u001b[0m protocol \u001b[38;5;241m=\u001b[39m req\u001b[38;5;241m.\u001b[39mtype\n\u001b[0;32m--> 536\u001b[0m result \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_call_chain\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mhandle_open\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mprotocol\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mprotocol\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m+\u001b[39;49m\n\u001b[1;32m 537\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;124;43m_open\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mreq\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 538\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m result:\n\u001b[1;32m 539\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m result\n", + "File \u001b[0;32m/opt/conda/lib/python3.10/urllib/request.py:496\u001b[0m, in \u001b[0;36mOpenerDirector._call_chain\u001b[0;34m(self, chain, kind, meth_name, *args)\u001b[0m\n\u001b[1;32m 494\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m handler \u001b[38;5;129;01min\u001b[39;00m handlers:\n\u001b[1;32m 495\u001b[0m func \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mgetattr\u001b[39m(handler, meth_name)\n\u001b[0;32m--> 496\u001b[0m result \u001b[38;5;241m=\u001b[39m \u001b[43mfunc\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 497\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m result \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[1;32m 498\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m result\n", + "File \u001b[0;32m/opt/conda/lib/python3.10/urllib/request.py:1391\u001b[0m, in \u001b[0;36mHTTPSHandler.https_open\u001b[0;34m(self, req)\u001b[0m\n\u001b[1;32m 1390\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mhttps_open\u001b[39m(\u001b[38;5;28mself\u001b[39m, req):\n\u001b[0;32m-> 1391\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mdo_open\u001b[49m\u001b[43m(\u001b[49m\u001b[43mhttp\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mclient\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mHTTPSConnection\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mreq\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 1392\u001b[0m \u001b[43m \u001b[49m\u001b[43mcontext\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_context\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mcheck_hostname\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_check_hostname\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[0;32m/opt/conda/lib/python3.10/urllib/request.py:1351\u001b[0m, in \u001b[0;36mAbstractHTTPHandler.do_open\u001b[0;34m(self, http_class, req, **http_conn_args)\u001b[0m\n\u001b[1;32m 1348\u001b[0m h\u001b[38;5;241m.\u001b[39mrequest(req\u001b[38;5;241m.\u001b[39mget_method(), req\u001b[38;5;241m.\u001b[39mselector, req\u001b[38;5;241m.\u001b[39mdata, headers,\n\u001b[1;32m 1349\u001b[0m encode_chunked\u001b[38;5;241m=\u001b[39mreq\u001b[38;5;241m.\u001b[39mhas_header(\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mTransfer-encoding\u001b[39m\u001b[38;5;124m'\u001b[39m))\n\u001b[1;32m 1350\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mOSError\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m err: \u001b[38;5;66;03m# timeout error\u001b[39;00m\n\u001b[0;32m-> 1351\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m URLError(err)\n\u001b[1;32m 1352\u001b[0m r \u001b[38;5;241m=\u001b[39m h\u001b[38;5;241m.\u001b[39mgetresponse()\n\u001b[1;32m 1353\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m:\n", + "\u001b[0;31mURLError\u001b[0m: " + ] + } + ], "source": [ "import os\n", "import urllib.request\n", @@ -554,7 +593,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 11, "metadata": {}, "outputs": [ { @@ -567,7 +606,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "c400551d3f144a80b0afee76ea6df334", + "model_id": "caecdff147b64f319e5f295a8f92dddc", "version_major": 2, "version_minor": 0 }, @@ -632,7 +671,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 12, "metadata": {}, "outputs": [ { @@ -654,7 +693,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 13, "metadata": {}, "outputs": [], "source": [ @@ -674,13 +713,13 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 14, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "417807b6e51542c28782297037ef86c7", + "model_id": "321da9b6e6d746ee868684c5bae33426", "version_major": 2, "version_minor": 0 }, @@ -741,13 +780,13 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "00b924157b074714a11e7c951cb3c8cb", + "model_id": "e89c67067474404798507a1d6eb92295", "version_major": 2, "version_minor": 0 }, @@ -772,7 +811,7 @@ "Name: Avg Tanimoto, dtype: float64" ] }, - "execution_count": 14, + "execution_count": 15, "metadata": {}, "output_type": "execute_result" } @@ -799,36 +838,25 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 17, "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAjsAAAHFCAYAAAAUpjivAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjYuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8o6BhiAAAACXBIWXMAAA9hAAAPYQGoP6dpAABPrElEQVR4nO3deVhUZf8G8HsYYBhW2RwGQVRSVEAxKRQzURT3rUVLM0kry+WVzHw1K6FF0rdccisLcV9eS9BX0MJcETM1yVAzNdxykDQUUGR9fn/04+QIDNsw4PH+XNdcF/PMc875PmcOw83ZRiGEECAiIiKSKbP6LoCIiIioLjHsEBERkawx7BAREZGsMewQERGRrDHsEBERkawx7BAREZGsMewQERGRrDHsEBERkawx7BAREZGsMexQpVauXAmFQiE9rKys4Obmhu7duyM6OhqZmZllpomMjIRCoajWcu7cuYPIyEjs3bu3WtOVt6xmzZphwIAB1ZpPZdavX48FCxaU+5pCoUBkZKRRl2ds33//PQIDA2FjYwOFQoH4+Pj6LumBtHfvXr3fB0MPYyr9Pbxw4YJR51sVp06dQmRkZL0suyafJTWZZ0hICEJCQoy6HODvz6Lw8HDp+dWrVxEZGYnU1FSjL4sqZl7fBdCDIzY2Fq1bt0ZhYSEyMzORnJyMOXPm4JNPPsGmTZvQs2dPqe/LL7+MPn36VGv+d+7cQVRUFABU60OnJsuqifXr1yMtLQ0RERFlXjt06BA8PDzqvIaaEkJg2LBhaNWqFbZt2wYbGxv4+PjUd1kPpEcffRSHDh3Saxs6dCi8vb3xySef1Nly+/fvj0OHDkGr1dbZMipy6tQpREVFISQkBM2aNTPpsuvi99tUnxkAEBcXB3t7e+n51atXERUVhWbNmiEgIMAkNRDDDlWDn58fAgMDpedPP/003njjDTzxxBN46qmncPbsWWg0GgCAh4dHnf/xv3PnDqytrU2yrMp06tSpXpdfmatXr+Kvv/7C0KFDERoaWt/lVEteXh7UanV9lyGxt7cv836rVCo0atSoTrcDV1dXuLq61tn8G6q6+P02xWdG6XbboUOHOl0OVQ0PY1GtNG3aFJ9++ilycnLwxRdfSO3l7SbevXs3QkJC4OzsDLVajaZNm+Lpp5/GnTt3cOHCBemDPCoqSjoMULr7t3R+P/30E5555hk4OjrC29u7wmWViouLQ7t27WBlZYUWLVrgs88+03u9okMDpYcqSg+phYSEICEhARcvXiz3MEV5h7HS0tIwePBgODo6wsrKCgEBAVi1alW5y9mwYQNmzpwJd3d32Nvbo2fPnjhz5kzFK/4eycnJCA0NhZ2dHaytrREcHIyEhATp9cjISOmD/d///jcUCoXB/87v3r2LN998EwEBAXBwcICTkxM6d+6MrVu36vXr0KEDunbtWmb64uJiNGnSBE899ZTUVlBQgA8//BCtW7eGSqWCq6srXnrpJfz5559605YeftyyZQs6dOgAKysraW/fkiVL8OSTT6Jx48awsbGBv78/5s6di8LCQr15CCEwe/ZseHl5wcrKCoGBgUhKSir3MEV2djamTp2K5s2bw9LSEk2aNEFERARu375d8QqvgqquQ+DvbWfixIlYs2YN2rRpA2tra7Rv3x7bt2/X61fethoSEgI/Pz8cOnQIwcHBUKvVaNasGWJjYwEACQkJePTRR2FtbQ1/f3/s3LmzzPIr235WrlyJZ599FgDQvXt3adtfuXKl1GfFihVo3749rKys4OTkhKFDh+L06dOVrqc7d+5I67902sDAQGzYsEHqY+gw9fbt29GhQweo1Wq0adNGWmcrV65EmzZtYGNjg8cffxxHjx7Vm76qh8aioqIQFBQEJycn2Nvb49FHH0VMTAzu//5sQ9vtvYex9u7di8ceewwA8NJLL0nrMjIyEmvWrIFCoSiz1xAA3n//fVhYWODq1auV1kwVEESViI2NFQDEkSNHyn09NzdXKJVKERoaKrXNmjVL3Lt5paenCysrK9GrVy8RHx8v9u7dK9atWydGjRolsrKyxN27d8XOnTsFADF27Fhx6NAhcejQIXHu3Dm9+Xl5eYl///vfIikpScTHx5e7LCGE8PLyEk2aNBFNmzYVK1asEImJiWLkyJECgPjPf/5TZmzp6el60+/Zs0cAEHv27BFCCHHy5EnRpUsX4ebmJtV26NAhqT8AMWvWLOn5r7/+Kuzs7IS3t7dYvXq1SEhIEM8//7wAIObMmVNmOc2aNRMjR44UCQkJYsOGDaJp06aiZcuWoqioyOB7s3fvXmFhYSE6duwoNm3aJOLj40VYWJhQKBRi48aNQgghLl++LLZs2SIAiEmTJolDhw6Jn376qcJ53rx5U4SHh4s1a9aI3bt3i507d4qpU6cKMzMzsWrVKqnfwoULBQDx22+/6U2fmJgoAIht27YJIYQoLi4Wffr0ETY2NiIqKkokJSWJr776SjRp0kS0bdtW3LlzR+9902q1okWLFmLFihViz5494scffxRCCPHGG2+IZcuWiZ07d4rdu3eL+fPnCxcXF/HSSy/pLX/GjBkCgHj11VfFzp07xZdffimaNm0qtFqt6Natm9Tv9u3bIiAgQLi4uIh58+aJXbt2iYULFwoHBwfRo0cPUVJSYnDd38vLy0v079+/2utQCCG9/48//rj473//KxITE0VISIgwNzcX58+fl/qVt61269ZNODs7Cx8fHxETEyO+/fZbMWDAAAFAREVFCX9/f7FhwwaRmJgoOnXqJFQqlfjjjz+k6auy/WRmZorZs2cLAGLJkiXStp+ZmSmEENJrzz//vEhISBCrV68WLVq0EA4ODmW2jfuNGzdOWFtbi3nz5ok9e/aI7du3i48//lgsWrRI6lPR77eHh4fw8/OTxhcUFCQsLCzEe++9J7p06SK2bNki4uLiRKtWrYRGo9HbzsqbZ7du3fS2DyGECA8PFzExMSIpKUkkJSWJDz74QKjVahEVFVWmnoq2Wy8vLzF69GghhBC3bt2S3sd33nlHWpeXL18W+fn5ws3NTYwcOVJv3oWFhcLd3V08++yzBtclGcawQ5WqLOwIIYRGoxFt2rSRnt//YfL1118LACI1NbXCefz5559lQsP983vvvfcqfO1eXl5eQqFQlFler169hL29vbh9+7be2CoLO0II0b9/f+Hl5VVu7ffX/dxzzwmVSiUuXbqk169v377C2tpa3Lx5U285/fr10+v33//+VwDQC1Tl6dSpk2jcuLHIycmR2oqKioSfn5/w8PCQ/mCnp6eXCXpVVVRUJAoLC8XYsWNFhw4dpPbr168LS0tL8fbbb+v1HzZsmNBoNKKwsFAIIcSGDRsEAPHNN9/o9Tty5IgAIJYuXSq1eXl5CaVSKc6cOWOwpuLiYlFYWChWr14tlEql+Ouvv4QQQvz1119CpVKJ4cOH6/U/dOiQAKD3xyw6OlqYmZmV2a5Lt9XExMRK1sw/7g8796toHQrx97aj0WhEdna21JaRkSHMzMxEdHS01FZR2AEgjh49KrXduHFDKJVKoVar9YJNamqqACA+++wzqa2q28/mzZvL/D4IIURWVpZQq9Vltt9Lly4JlUolRowYUeE6EUIIPz8/MWTIEIN9Kvr9VqvV4sqVK2XGp9Vqpd9vIYSIj4/XC98VzbO8sHOv0m3u/fffF87Oznph2NB2e2/YEeKf7T42NrbcsVpaWopr165JbZs2bRIAxL59+yqsjSrHw1hkFOK+3br3CwgIgKWlJV599VWsWrUKv//+e42W8/TTT1e5r6+vL9q3b6/XNmLECGRnZ+Onn36q0fKravfu3QgNDYWnp6dee3h4OO7cuVNmV/WgQYP0nrdr1w4AcPHixQqXcfv2bRw+fBjPPPMMbG1tpXalUolRo0bhypUrVT4Udr/NmzejS5cusLW1hbm5OSwsLBATE6N3aMLZ2RkDBw7EqlWrUFJSAgDIysrC1q1b8eKLL8Lc/O9TArdv345GjRph4MCBKCoqkh4BAQFwc3Mrc/Vdu3bt0KpVqzI1HT9+HIMGDYKzszOUSiUsLCzw4osvori4GL/99hsA4IcffkB+fj6GDRumN22nTp3KHLrbvn07/Pz8EBAQoFdX79699Q5h1lRV1mGp7t27w87OTnqu0WjQuHFjg+9/Ka1Wi44dO0rPnZyc0LhxYwQEBMDd3V1qb9OmDYB/tiljbD+HDh1CXl6e3tVGAODp6YkePXrg+++/Nzj9448/jh07dmD69OnYu3cv8vLyKh1vqYCAADRp0qTM+EJCQmBtbV2mvSrr8n67d+9Gz5494eDgIG1z7733Hm7cuFHmKtSKttvqeP311wEAX375pdS2ePFi+Pv748knn6zVvB92DDtUa7dv38aNGzf0Pljv5+3tjV27dqFx48aYMGECvL294e3tjYULF1ZrWdW5EsXNza3Cths3blRrudV148aNcmstXUf3L9/Z2VnvuUqlAgCDH/5ZWVkQQlRrOVWxZcsWDBs2DE2aNMHatWtx6NAhHDlyBGPGjMHdu3f1+o4ZMwZ//PEHkpKSAAAbNmxAfn6+3h+/a9eu4ebNm7C0tISFhYXeIyMjA9evX9ebZ3njuXTpErp27Yo//vgDCxcuxIEDB3DkyBEsWbIEwD/rqXS8pSfK3+v+tmvXruHEiRNlarKzs4MQokxd1VGddQiUff+Bv7eBqvzxd3JyKtNmaWlZpt3S0hIApOUbY/spfb2ieVQ2/WeffYZ///vfiI+PR/fu3eHk5IQhQ4bg7NmzBqcDyo67dHyVjbuqfvzxR4SFhQH4O3wcPHgQR44cwcyZMwGU/d00xlVyGo0Gw4cPxxdffIHi4mKcOHECBw4cwMSJE2s974cdr8aiWktISEBxcXGll4t37doVXbt2RXFxMY4ePYpFixYhIiICGo0Gzz33XJWWVZ37bWRkZFTYVvrHxcrKCgCQn5+v1682f+hK56/T6cq0l55g6OLiUqv5A4CjoyPMzMyMvpy1a9eiefPm2LRpk976vn8dAUDv3r3h7u6O2NhY9O7dG7GxsQgKCkLbtm2lPi4uLnB2di735FgAens0gPLf4/j4eNy+fRtbtmyBl5eX1H7/vUpK39dr166VmUdGRobe3h0XFxeo1WqsWLGi3Lpq8x5VZx3WF2NsP6Xru6J5VDa9jY0NoqKiEBUVhWvXrkl7eQYOHIhff/21qkOpExs3boSFhQW2b98ufU4AqPD+VMa6F9DkyZOxZs0abN26FTt37kSjRo0wcuRIo8z7YcY9O1Qrly5dwtSpU+Hg4IBx48ZVaRqlUomgoCDpv/LSQ0pV2ZtRHSdPnsTPP/+s17Z+/XrY2dnh0UcfBQDpj9+JEyf0+m3btq3M/Kr6nzYAhIaGYvfu3WWunli9ejWsra2NcomyjY0NgoKCsGXLFr26SkpKsHbtWnh4eNRot7pCoYClpaXeh3dGRka5VxKVHvKIj4/HgQMHcPToUYwZM0avz4ABA3Djxg0UFxcjMDCwzKMq9/spraV0GwH+PnR67+5+AAgKCoJKpcKmTZv02n/44YcyhzEGDBiA8+fPw9nZudy6anM/meqsw/pSne2not/Nzp07Q61WY+3atXrtV65ckQ7lVpVGo0F4eDief/55nDlzBnfu3Knp0IxCoVDA3NwcSqVSasvLy8OaNWtqNd/KPuc6duyI4OBgzJkzB+vWrUN4eDhsbGxqtUzinh2qhrS0NOm8hszMTBw4cACxsbFQKpWIi4szeA+Qzz//HLt370b//v3RtGlT3L17V/qPuvRmhHZ2dvDy8sLWrVsRGhoKJycnuLi41PiPjru7OwYNGoTIyEhotVqsXbsWSUlJmDNnjnRM/7HHHoOPjw+mTp2KoqIiODo6Ii4uDsnJyWXm5+/vjy1btmDZsmXo2LEjzMzM9O47dK9Zs2Zh+/bt6N69O9577z04OTlh3bp1SEhIwNy5c+Hg4FCjMd0vOjoavXr1Qvfu3TF16lRYWlpi6dKlSEtLw4YNG2r032bpJbTjx4/HM888g8uXL+ODDz6AVqst9/DCmDFjMGfOHIwYMQJqtRrDhw/Xe/25557DunXr0K9fP0yePBmPP/44LCwscOXKFezZsweDBw/G0KFDDdbUq1cvWFpa4vnnn8e0adNw9+5dLFu2DFlZWXr9nJycMGXKFERHR8PR0RFDhw7FlStXEBUVBa1WCzOzf/6/i4iIwDfffIMnn3wSb7zxBtq1a4eSkhJcunQJ3333Hd58800EBQVVe/3VZB3Wl6puP35+fgCA5cuXw87ODlZWVmjevDmcnZ3x7rvv4u2338aLL76I559/Hjdu3EBUVBSsrKwwa9Ysg8sPCgrCgAED0K5dOzg6OuL06dNYs2YNOnfurHfeTX3o378/5s2bhxEjRuDVV1/FjRs38Mknn+gF7prw9vaGWq3GunXr0KZNG9ja2sLd3V3vNIDJkydj+PDhUCgUGD9+fG2HQgAvPafKlV4FUvqwtLQUjRs3Ft26dROzZ8+WLkG91/1XOxw6dEgMHTpUeHl5CZVKJZydnUW3bt30rpAQQohdu3aJDh06CJVKJQBIVzGUzu/PP/+sdFlC/HN1zNdffy18fX2FpaWlaNasmZg3b16Z6X/77TcRFhYm7O3thaurq5g0aZJISEgoc/XJX3/9JZ555hnRqFEjoVAo9JaJcq4i++WXX8TAgQOFg4ODsLS0FO3bty9zBUbp1VibN2/Way+9eqq8Kzbud+DAAdGjRw9hY2Mj1Gq16NSpk/jf//5X7vyqejXWxx9/LJo1ayZUKpVo06aN+PLLL8tdz6WCg4MFgDKXzZYqLCwUn3zyiWjfvr2wsrIStra2onXr1mLcuHHi7NmzUj9DVzX973//k6Zv0qSJeOutt8SOHTvKvE8lJSXiww8/FB4eHsLS0lK0a9dObN++XbRv314MHTpUb565ubninXfeET4+PsLS0lI4ODgIf39/8cYbb4iMjIwqrauK6q7qOgQgJkyYUO48772Kp6KrsXx9fatUT0XLqsr2I4QQCxYsEM2bNxdKpbLMtvnVV1+Jdu3aSetw8ODB4uTJk2Xmcb/p06eLwMBA4ejoKFQqlWjRooV44403xPXr16U+hn6/qzK+8rb9ql6NtWLFCuHj4yPVFh0dLWJiYsq8D4a22/vfRyH+vkKxdevWwsLCotzPjvz8fKFSqUSfPn3KnSdVn0KISi6jISJ6wKWnp6N169aYNWsW3n777fouh8ig//3vfxg0aBASEhLQr1+/+i5HFhh2iEhWfv75Z2zYsAHBwcGwt7fHmTNnMHfuXGRnZyMtLa3cK7WIGoJTp07h4sWLmDx5MmxsbPDTTz8Z/UtQH1Y8Z4eIZMXGxgZHjx5FTEwMbt68CQcHB4SEhOCjjz5i0KEGbfz48Th48CAeffRRrFq1ikHHiLhnh4iIiGSNl54TERGRrDHsEBERkawx7BAREZGs8QRl/H3H0KtXr8LOzo4nhBERET0ghBDIycmBu7u73k1D78ewg7+/w+X+b6cmIiKiB8Ply5fh4eFR4esMO/jniwgvX74Me3v7eq6GiIiIqiI7Oxuenp5lvlD4fgw7+OdLBu3t7Rl2iIiIHjCVnYLCE5SJiIhI1hh2iIiISNYYdoiIiEjWGHaIiIhI1hh2iIiISNYYdoiIiEjWGHaIiIhI1hh2iIiISNYYdoiIiEjWGHaIiIhI1hh2iIiISNYYdoiIiEjWGHaIiIhI1hh2iIiISNYYdoiIiEjWzOu7ACIiqju+7QKg0+kM9tFqtTh5ItU0BRHVg3oNO8uWLcOyZctw4cIFAICvry/ee+899O3bFwAghEBUVBSWL1+OrKwsBAUFYcmSJfD19ZXmkZ+fj6lTp2LDhg3Iy8tDaGgoli5dCg8Pj/oYEhFRg6LT6RD2UbzBPt/NHGKSWojqS70exvLw8MDHH3+Mo0eP4ujRo+jRowcGDx6MkydPAgDmzp2LefPmYfHixThy5Ajc3NzQq1cv5OTkSPOIiIhAXFwcNm7ciOTkZOTm5mLAgAEoLi6ur2ERERFRA6IQQoj6LuJeTk5O+M9//oMxY8bA3d0dERER+Pe//w3g7704Go0Gc+bMwbhx43Dr1i24urpizZo1GD58OADg6tWr8PT0RGJiInr37l2lZWZnZ8PBwQG3bt2Cvb19nY2NiMjUnFw1Vdqz89ef10xTEJERVfXvd4M5Z6e4uBibN2/G7du30blzZ6SnpyMjIwNhYWFSH5VKhW7duiElJQXjxo3DsWPHUFhYqNfH3d0dfn5+SElJqTDs5OfnIz8/X3qenZ0t1cA9QkQkJ+bm5jCD4f9pzc3N+dlHD6Sqbrf1HnZ++eUXdO7cGXfv3oWtrS3i4uLQtm1bpKSkAAA0Go1ef41Gg4sXLwIAMjIyYGlpCUdHxzJ9MjIyKlxmdHQ0oqKiyrSfP38etra2tR0SEVGD0b9fX3jb3DbYR9WvL86ePWuiioiMJzc3t0r96j3s+Pj4IDU1FTdv3sQ333yD0aNHY9++fdLrCoVCr78Qokzb/SrrM2PGDEyZMkV6np2dDU9PT3h7e/MwFhHJSkLiDvQMGmOwz67EHfhq+RcmqojIeEqPzFSm3sOOpaUlHnnkEQBAYGAgjhw5goULF0rn6WRkZECr1Ur9MzMzpb09bm5uKCgoQFZWlt7enczMTAQHB1e4TJVKBZVKVaZdqVRCqVQaZVxERA1BUVERSmD4H8SioiJ+9tEDqarbbYO7qaAQAvn5+WjevDnc3NyQlJQkvVZQUIB9+/ZJQaZjx46wsLDQ66PT6ZCWlmYw7BAREdHDo1737Lz99tvo27cvPD09kZOTg40bN2Lv3r3YuXMnFAoFIiIiMHv2bLRs2RItW7bE7NmzYW1tjREjRgAAHBwcMHbsWLz55ptwdnaGk5MTpk6dCn9/f/Ts2bM+h0ZEREQNRL2GnWvXrmHUqFHQ6XRwcHBAu3btsHPnTvTq1QsAMG3aNOTl5WH8+PHSTQW/++472NnZSfOYP38+zM3NMWzYMOmmgitXruQuWSIiIgLQAO+zUx94nx0ikiveZ4fkrKp/vxvcOTtERERExsSwQ0RERLLGsENERESyxrBDREREssawQ0RERLLGsENERESyxrBDREREssawQ0RERLLGsENERESyxrBDREREssawQ0RERLLGsENERESyxrBDREREssawQ0RERLLGsENERESyxrBDREREssawQ0RERLLGsENERESyZl7fBRARUc34tguATqcz2Cc7J8dE1RA1XAw7REQPKJ1Oh7CP4g322Tyxh2mKIWrAeBiLiIiIZI1hh4iIiGSNYYeIiIhkjWGHiIiIZI1hh4iIiGSNYYeIiIhkjWGHiIiIZI1hh4iIiGSNYYeIiIhkjWGHiIiIZI1hh4iIiGSNYYeIiIhkjWGHiIiIZI3fek5E9JDLzsmFk6vGYB+tVouTJ1JNUxCRkTHsEBE1QL7tAqDT6Qz2yc7JMcqyREkJwj6KN9jnu5lDjLIsovrAsENE1ADpdLpKA8jmiT1MUwzRA47n7BAREZGsMewQERGRrDHsEBERkawx7BAREZGsMewQERGRrDHsEBERkawx7BAREZGsMewQERGRrDHsEBERkawx7BAREZGsMewQERGRrNVr2ImOjsZjjz0GOzs7NG7cGEOGDMGZM2f0+oSHh0OhUOg9OnXqpNcnPz8fkyZNgouLC2xsbDBo0CBcuXLFlEMhIiKiBqpew86+ffswYcIE/PDDD0hKSkJRURHCwsJw+/ZtvX59+vSBTqeTHomJiXqvR0REIC4uDhs3bkRycjJyc3MxYMAAFBcXm3I4RERE1ADV67ee79y5U+95bGwsGjdujGPHjuHJJ5+U2lUqFdzc3Mqdx61btxATE4M1a9agZ8+eAIC1a9fC09MTu3btQu/evetuAERERNTg1WvYud+tW7cAAE5OTnrte/fuRePGjdGoUSN069YNH330ERo3bgwAOHbsGAoLCxEWFib1d3d3h5+fH1JSUsoNO/n5+cjPz5eeZ2dnAwCKi4u5N4iIGgRzc3OYQTSoPvx8pIamqttkgwk7QghMmTIFTzzxBPz8/KT2vn374tlnn4WXlxfS09Px7rvvokePHjh27BhUKhUyMjJgaWkJR0dHvflpNBpkZGSUu6zo6GhERUWVaT9//jxsbW2NOzAiohro368vvG1uG+40dAjamqiPql9fnD171vB8iEwsNze3Sv0aTNiZOHEiTpw4geTkZL324cOHSz/7+fkhMDAQXl5eSEhIwFNPPVXh/IQQUCgU5b42Y8YMTJkyRXqenZ0NT09PeHt7w97evpYjISKqvYTEHegZNMZgn2/i4oFur5ukz67EHfhq+RcG+xCZWumRmco0iLAzadIkbNu2Dfv374eHh4fBvlqtFl5eXtJ/GG5ubigoKEBWVpbe3p3MzEwEBweXOw+VSgWVSlWmXalUQqlU1mIkRETGUVRUhBKU/w9bffXh5yM1NFXdJuv1aiwhBCZOnIgtW7Zg9+7daN68eaXT3LhxA5cvX4ZWqwUAdOzYERYWFkhKSpL66HQ6pKWlVRh2iIiI6OFRr3t2JkyYgPXr12Pr1q2ws7OTzrFxcHCAWq1Gbm4uIiMj8fTTT0Or1eLChQt4++234eLigqFDh0p9x44dizfffBPOzs5wcnLC1KlT4e/vL12dRURERA+veg07y5YtAwCEhITotcfGxiI8PBxKpRK//PILVq9ejZs3b0Kr1aJ79+7YtGkT7OzspP7z58+Hubk5hg0bhry8PISGhmLlypXc5UpERET1G3aEMHypo1qtxrffflvpfKysrLBo0SIsWrTIWKURERGRTPC7sYiIiEjWGHaIiIhI1hh2iIiISNYYdoiIiEjWGHaIiIhI1hh2iIiISNYYdoiIiEjWGHaIiIhI1hh2iIiISNYYdoiIiEjWGHaIiIhI1hh2iIiISNYYdoiIiEjWGHaIiIhI1hh2iIiISNYYdoiIiEjWGHaIiIhI1hh2iIiISNYYdoiIiEjWGHaIiIhI1hh2iIiISNYYdoiIiEjWGHaIiIhI1hh2iIiISNYYdoiIiEjWGHaIiIhI1hh2iIiISNYYdoiIiEjWGHaIiIhI1hh2iIiISNYYdoiIiEjWGHaIiIhI1hh2iIiISNYYdoiIiEjWGHaIiIhI1hh2iIiISNYYdoiIiEjWGHaIiIhI1hh2iIiISNYYdoiIiEjWGHaIiIhI1hh2iIiISNYYdoiIiEjWGHaIiIhI1hh2iIiISNYYdoiIiEjWGHaIiIhI1uo17ERHR+Oxxx6DnZ0dGjdujCFDhuDMmTN6fYQQiIyMhLu7O9RqNUJCQnDy5Em9Pvn5+Zg0aRJcXFxgY2ODQYMG4cqVK6YcChERETVQ9Rp29u3bhwkTJuCHH35AUlISioqKEBYWhtu3b0t95s6di3nz5mHx4sU4cuQI3Nzc0KtXL+Tk5Eh9IiIiEBcXh40bNyI5ORm5ubkYMGAAiouL62NYRERE1ICY1+fCd+7cqfc8NjYWjRs3xrFjx/Dkk09CCIEFCxZg5syZeOqppwAAq1atgkajwfr16zFu3DjcunULMTExWLNmDXr27AkAWLt2LTw9PbFr1y707t3b5OMiIiKihqNew879bt26BQBwcnICAKSnpyMjIwNhYWFSH5VKhW7duiElJQXjxo3DsWPHUFhYqNfH3d0dfn5+SElJKTfs5OfnIz8/X3qenZ0NACguLubeICJqEMzNzWEG0aD68PORGpqqbpMNJuwIITBlyhQ88cQT8PPzAwBkZGQAADQajV5fjUaDixcvSn0sLS3h6OhYpk/p9PeLjo5GVFRUmfbz58/D1ta21mMhIqqt/v36wtvmtuFOQ4egrYn6qPr1xdmzZw3Ph8jEcnNzq9SvwYSdiRMn4sSJE0hOTi7zmkKh0HsuhCjTdj9DfWbMmIEpU6ZIz7Ozs+Hp6Qlvb2/Y29vXoHoiIuNKSNyBnkFjDPb5Ji4e6Pa6SfrsStyBr5Z/YbAPkamVHpmpTIMIO5MmTcK2bduwf/9+eHh4SO1ubm4A/t57o9VqpfbMzExpb4+bmxsKCgqQlZWlt3cnMzMTwcHB5S5PpVJBpVKVaVcqlVAqlUYZExFRbRQVFaEEhv+pM3Uffj5SQ1PVbbJer8YSQmDixInYsmULdu/ejebNm+u93rx5c7i5uSEpKUlqKygowL59+6Qg07FjR1hYWOj10el0SEtLqzDsEBER0cOjXvfsTJgwAevXr8fWrVthZ2cnnWPj4OAAtVoNhUKBiIgIzJ49Gy1btkTLli0xe/ZsWFtbY8SIEVLfsWPH4s0334SzszOcnJwwdepU+Pv7S1dnERER0cOrXsPOsmXLAAAhISF67bGxsQgPDwcATJs2DXl5eRg/fjyysrIQFBSE7777DnZ2dlL/+fPnw9zcHMOGDUNeXh5CQ0OxcuVK7nIlIiKi+g07Qhi+1BH4++TkyMhIREZGVtjHysoKixYtwqJFi4xYHREREckBvxuLiIiIZI1hh4iIiGSNYYeIiIhkjWGHiIiIZI1hh4iIiGSNYYeIiIhkjWGHiIiIZI1hh4iIiGSNYYeIiIhkjWGHiIiIZI1hh4iIiGSNYYeIiIhkjWGHiIiIZI1hh4iIiGSNYYeIiIhkjWGHiIiIZI1hh4iIiGSNYYeIiIhkjWGHiIiIZI1hh4iIiGSNYYeIiIhkrUZhp0WLFrhx40aZ9ps3b6JFixa1LoqIiIjIWMxrMtGFCxdQXFxcpj0/Px9//PFHrYsiIqKGJTsnF06uGoN9tFotTp5INU1BRNVQrbCzbds26edvv/0WDg4O0vPi4mJ8//33aNasmdGKIyKihkGUlCDso3iDfb6bOcQktRBVV7XCzpAhQwAACoUCo0eP1nvNwsICzZo1w6effmq04oiIiIhqq1php6SkBADQvHlzHDlyBC4uLnVSFBEREZGx1OicnfT0dGPXQURERFQnahR2AOD777/H999/j8zMTGmPT6kVK1bUujAiIiIiY6hR2ImKisL777+PwMBAaLVaKBQKY9dFREREZBQ1Cjuff/45Vq5ciVGjRhm7HiIiIiKjqtFNBQsKChAcHGzsWoiIiIiMrkZh5+WXX8b69euNXQsRERGR0dXoMNbdu3exfPly7Nq1C+3atYOFhYXe6/PmzTNKcURERES1VaOwc+LECQQEBAAA0tLS9F7jycpERETUkNQo7OzZs8fYdRARPTR82wVAp9MZ7JOdk2Oiaojkr8b32SEioprR6XSVfs/U5ok9TFMM0UOgRmGne/fuBg9X7d69u8YFERERERlTjcJO6fk6pQoLC5Gamoq0tLQyXxBKREREVJ9qFHbmz59fbntkZCRyc3NrVRARERGRMdXoPjsVeeGFF/i9WERERNSgGDXsHDp0CFZWVsacJREREVGt1Ogw1lNPPaX3XAgBnU6Ho0eP4t133zVKYURERETGUKOw4+DgoPfczMwMPj4+eP/99xEWFmaUwoiIiIiMoUZhJzY21th1EBEREdWJWt1U8NixYzh9+jQUCgXatm2LDh06GKsuIiIiIqOoUdjJzMzEc889h71796JRo0YQQuDWrVvo3r07Nm7cCFdXV2PXSURERFQjNboaa9KkScjOzsbJkyfx119/ISsrC2lpacjOzsa//vWvKs9n//79GDhwINzd3aFQKBAfH6/3enh4OBQKhd6jU6dOen3y8/MxadIkuLi4wMbGBoMGDcKVK1dqMiwiIiKSoRqFnZ07d2LZsmVo06aN1Na2bVssWbIEO3bsqPJ8bt++jfbt22Px4sUV9unTpw90Op30SExM1Hs9IiICcXFx2LhxI5KTk5Gbm4sBAwaguLi4+gMjIiIi2anRYaySkhJYWFiUabewsEBJSUmV59O3b1/07dvXYB+VSgU3N7dyX7t16xZiYmKwZs0a9OzZEwCwdu1aeHp6YteuXejdu3eVayEiIiJ5qtGenR49emDy5Mm4evWq1PbHH3/gjTfeQGhoqNGKA4C9e/eicePGaNWqFV555RVkZmZKrx07dgyFhYV6l7u7u7vDz88PKSkpRq2DiIiIHkw12rOzePFiDB48GM2aNYOnpycUCgUuXboEf39/rF271mjF9e3bF88++yy8vLyQnp6Od999Fz169MCxY8egUqmQkZEBS0tLODo66k2n0WiQkZFR4Xzz8/ORn58vPc/OzgYAFBcX8/AXEdU5c3NzmEHIsg8/Q8mUqrq91SjseHp64qeffkJSUhJ+/fVXCCHQtm1b6VCSsQwfPlz62c/PD4GBgfDy8kJCQkKZuzjfSwgBhUJR4evR0dGIiooq037+/HnY2trWrmgiokr079cX3ja3DXcaOgRtH7A+qn59cfbsWcPzITKiqn75eLXCzu7duzFx4kT88MMPsLe3R69evdCrVy8Af58/4+vri88//xxdu3atfsVVoNVq4eXlJf0yubm5oaCgAFlZWXp7dzIzMxEcHFzhfGbMmIEpU6ZIz7Ozs+Hp6Qlvb2/Y29vXSe1ERKUSEnegZ9AYg32+iYsHur3+QPXZlbgDXy3/wmAfImMqPTJTmWqFnQULFuCVV14pNxA4ODhg3LhxmDdvXp2FnRs3buDy5cvQarUAgI4dO8LCwgJJSUkYNmwYAECn0yEtLQ1z586tcD4qlQoqlapMu1KphFKprJPaiYhKFRUVoQQV731+kPvwM5RMqarbW7VOUP7555/Rp0+fCl8PCwvDsWPHqjy/3NxcpKamIjU1FQCQnp6O1NRUXLp0Cbm5uZg6dSoOHTqECxcuYO/evRg4cCBcXFwwdOhQAH8HrLFjx+LNN9/E999/j+PHj+OFF16Av7+/0Q+pERER0YOpWnt2rl27Vu4l59LMzM3x559/Vnl+R48eRffu3aXnpYeWRo8ejWXLluGXX37B6tWrcfPmTWi1WnTv3h2bNm2CnZ2dNM38+fNhbm6OYcOGIS8vD6GhoVi5ciX/uyAiIiIA1Qw7TZo0wS+//IJHHnmk3NdPnDghHWKqipCQEAhR8dn93377baXzsLKywqJFi7Bo0aIqL5eIiIgeHtU6jNWvXz+89957uHv3bpnX8vLyMGvWLAwYMMBoxRERERHVVrX27LzzzjvYsmULWrVqhYkTJ8LHxwcKhQKnT5/GkiVLUFxcjJkzZ9ZVrURERETVVq2wo9FokJKSgtdffx0zZsyQDkEpFAr07t0bS5cuhUajqZNCiYiIiGqi2jcV9PLyQmJiIrKysnDu3DkIIdCyZcsydzEmIiIiaghqdAdlAHB0dMRjjz1mzFqIiB54vu0CoNPpDPbJzskxUTVEBNQi7BARUVk6nQ5hH8Ub7LN5Yg/TFENEAGr4redEREREDwqGHSIiIpI1hh0iIiKSNYYdIiIikjWGHSIiIpI1hh0iIiKSNYYdIiIikjWGHSIiIpI1hh0iIiKSNYYdIiIikjWGHSIiIpI1hh0iIiKSNYYdIiIikjWGHSIiIpI1hh0iIiKSNYYdIiIikjWGHSIiIpI1hh0iIiKSNYYdIiIikjWGHSIiIpI1hh0iIiKSNYYdIiIikjWGHSIiIpI1hh0iIiKSNYYdIiIikjWGHSIiIpI1hh0iIiKSNYYdIiIikjWGHSIiIpI1hh0iIiKSNYYdIiIikjWGHSIiIpI1hh0iIiKSNYYdIiIikjWGHSIiIpI18/ougIiI5CE7JxdOrhqDfbRaLU6eSDVNQUT/j2GHiIiMQpSUIOyjeIN9vps5xCS1EN2Lh7GIiIhI1hh2iIiISNYYdoiIiEjWGHaIiIhI1uo17Ozfvx8DBw6Eu7s7FAoF4uPj9V4XQiAyMhLu7u5Qq9UICQnByZMn9frk5+dj0qRJcHFxgY2NDQYNGoQrV66YcBRERETUkNVr2Ll9+zbat2+PxYsXl/v63LlzMW/ePCxevBhHjhyBm5sbevXqhZycHKlPREQE4uLisHHjRiQnJyM3NxcDBgxAcXGxqYZBREREDVi9Xnret29f9O3bt9zXhBBYsGABZs6ciaeeegoAsGrVKmg0Gqxfvx7jxo3DrVu3EBMTgzVr1qBnz54AgLVr18LT0xO7du1C7969TTYWIiIiapga7H120tPTkZGRgbCwMKlNpVKhW7duSElJwbhx43Ds2DEUFhbq9XF3d4efnx9SUlIqDDv5+fnIz8+XnmdnZwMAiouLuUeIiGrF3NwcZhDsY6APP2fJWKq6LTXYsJORkQEA0Gj078ap0Whw8eJFqY+lpSUcHR3L9CmdvjzR0dGIiooq037+/HnY2trWtnQieoj179cX3ja3DXcaOgRtH9I+qn59cfbsWcPzIaqi3NzcKvVrsGGnlEKh0HsuhCjTdr/K+syYMQNTpkyRnmdnZ8PT0xPe3t6wt7evXcFE9FBLSNyBnkFjDPb5Ji4e6Pb6Q9lnV+IOfLX8C4N9iKqq9MhMZRps2HFzcwPw994brVYrtWdmZkp7e9zc3FBQUICsrCy9vTuZmZkIDg6ucN4qlQoqlapMu1KphFKpNNYQiOghVFRUhBIY/ofsYe/Dz1kylqpuSw32PjvNmzeHm5sbkpKSpLaCggLs27dPCjIdO3aEhYWFXh+dToe0tDSDYYeIqCZ82wXAyVVj8JF9z9WiRNQw1OuendzcXJw7d056np6ejtTUVDg5OaFp06aIiIjA7Nmz0bJlS7Rs2RKzZ8+GtbU1RowYAQBwcHDA2LFj8eabb8LZ2RlOTk6YOnUq/P39pauziIiMRafTVfpFl5sn9jBNMURUZfUado4ePYru3btLz0vPoxk9ejRWrlyJadOmIS8vD+PHj0dWVhaCgoLw3Xffwc7OTppm/vz5MDc3x7Bhw5CXl4fQ0FCsXLmSu0mJiIgIQD2HnZCQEAhR8WWKCoUCkZGRiIyMrLCPlZUVFi1ahEWLFtVBhURERPSga7Dn7BAREREZA8MOERERyRrDDhEREckaww4RERHJGsMOERERyVqDvYMyERHJT3ZOLpxcNQb7aLVanDyRapqC6KHAsENERCYjSkoqvTHjdzOHmKQWenjwMBYRERHJGsMOERERyRrDDhEREckaww4RERHJGsMOERERyRrDDhEREckaww4RERHJGsMOERERyRrDDhEREckaww4RERHJGsMOERERyRrDDhEREckaww4RERHJGsMOERERyRrDDhEREckaww4RERHJGsMOERERyRrDDhEREckaww4RERHJGsMOERERyRrDDhEREckaww4RERHJGsMOERERyRrDDhEREckaww4RERHJGsMOERERyRrDDhEREckaww4RERHJmnl9F0BE1BD4tguATqcz2Cc7J8dE1RCRMTHsEBEB0Ol0CPso3mCfzRN7mKYYIjIqHsYiIiIiWWPYISIiIllj2CEiIiJZY9ghIiIiWWPYISIiIllj2CEiIiJZY9ghIiIiWWPYISIiIllj2CEiIiJZY9ghIiIiWWvQYScyMhIKhULv4ebmJr0uhEBkZCTc3d2hVqsREhKCkydP1mPFRERE1NA06LADAL6+vtDpdNLjl19+kV6bO3cu5s2bh8WLF+PIkSNwc3NDr169kMMv6yMiIqL/1+DDjrm5Odzc3KSHq6srgL/36ixYsAAzZ87EU089BT8/P6xatQp37tzB+vXr67lqIiIiaiga/Leenz17Fu7u7lCpVAgKCsLs2bPRokULpKenIyMjA2FhYVJflUqFbt26ISUlBePGjatwnvn5+cjPz5eeZ2dnAwCKi4tRXFxcd4MhogbL3NwcZhDs00D68LOYqqKq20mDDjtBQUFYvXo1WrVqhWvXruHDDz9EcHAwTp48iYyMDACARqPRm0aj0eDixYsG5xsdHY2oqKgy7efPn4etra3xBkBED4z+/frC2+a24U5Dh6At+9R5H1W/vjh79qzh+RAByM3NrVK/Bh12+vbtK/3s7++Pzp07w9vbG6tWrUKnTp0AAAqFQm8aIUSZtvvNmDEDU6ZMkZ5nZ2fD09MT3t7esLe3N+IIiOhBkZC4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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ - "# Plot the distribution of the average Tanimoto similarity\n", - "import seaborn as sns\n", - "import matplotlib.pyplot as plt\n", + "# # Plot the distribution of the average Tanimoto similarity\n", + "# import seaborn as sns\n", + "# import matplotlib.pyplot as plt\n", "\n", - "sns.histplot(protac_df['Avg Tanimoto'], bins=50)\n", - "plt.xlabel('Average Tanimoto similarity')\n", - "plt.ylabel('Count')\n", - "plt.title('Distribution of average Tanimoto similarity')\n", - "plt.grid(axis='y', alpha=0.5)\n", - "plt.show()" + "# sns.histplot(protac_df['Avg Tanimoto'], bins=50)\n", + "# plt.xlabel('Average Tanimoto similarity')\n", + "# plt.ylabel('Count')\n", + "# plt.title('Distribution of average Tanimoto similarity')\n", + "# plt.grid(axis='y', alpha=0.5)\n", + "# plt.show()" ] }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 18, "metadata": {}, "outputs": [], "source": [ @@ -844,7 +872,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 19, "metadata": {}, "outputs": [], "source": [ @@ -861,7 +889,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 20, "metadata": {}, "outputs": [], "source": [ @@ -870,7 +898,7 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 21, "metadata": {}, "outputs": [], "source": [ @@ -939,7 +967,7 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 22, "metadata": {}, "outputs": [], "source": [ @@ -950,7 +978,7 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 23, "metadata": {}, "outputs": [], "source": [ @@ -978,7 +1006,7 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 24, "metadata": {}, "outputs": [], "source": [ @@ -1037,63 +1065,63 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 26, "metadata": {}, "outputs": [], "source": [ - "import warnings\n", - "import seaborn as sns\n", - "import matplotlib.pyplot as plt\n", - "from sklearn.decomposition import PCA\n", - "from sklearn.preprocessing import StandardScaler\n", - "\n", - "def plot_pca(protac_data, protac_labels):\n", - " \"\"\" Plot the PCA embeddings.\n", + "if RUN_DIMENSIONALITY_REDUCTION:\n", + " import warnings\n", + " import seaborn as sns\n", + " import matplotlib.pyplot as plt\n", + " from sklearn.decomposition import PCA\n", + " from sklearn.preprocessing import StandardScaler\n", "\n", - " Args:\n", - " protac_data (np.ndarray): The PROTAC data.\n", - " protac_labels (dict): The labels for the PROTAC data.\n", - " \"\"\"\n", - " pca = PCA(n_components=2, random_state=42)\n", - " scaler = StandardScaler()\n", - " pca_data = pca.fit_transform(scaler.fit_transform(protac_data))\n", + " def plot_pca(protac_data, protac_labels):\n", + " \"\"\" Plot the PCA embeddings.\n", "\n", - " # Plot PCA accordingly\n", - " labels_to_plot = [\n", - " active_col,\n", - " 'Active - OR',\n", - " 'Cell Line Identifier',\n", - " 'E3 Ligase',\n", - " 'Uniprot',\n", - " # 'Smiles',\n", - " 'Treatment Time (h)',\n", - " 'DC50 (nM)',\n", - " 'Dmax (%)',\n", - " ]\n", - " for label in labels_to_plot:\n", - " if label not in protac_labels:\n", - " continue\n", - " pca_embeddings = {\n", - " 'PCA 1': pca_data[:, 0],\n", - " 'PCA 2': pca_data[:, 1],\n", - " label: protac_labels[label],\n", - " }\n", - " pca_embeddings = pd.DataFrame(pca_embeddings).drop_duplicates()\n", - " # Scatter plot\n", - " with warnings.catch_warnings():\n", - " warnings.simplefilter(\"ignore\")\n", - " sns.scatterplot(data=pca_embeddings, x='PCA 1', y='PCA 2',\n", - " hue=label) #, palette=sns.color_palette('tab10'))\n", - " # Plot legend for active and e3 ligase only\n", - " if label in [active_col, 'E3 Ligase']:\n", - " plt.legend(title=f'{label}:')\n", - " else:\n", - " plt.legend().remove()\n", - " plt.title(f'PCA embedding coloring for \"{label}\"')\n", - " plt.grid(axis='both', alpha=0.5)\n", - " plt.show()\n", + " Args:\n", + " protac_data (np.ndarray): The PROTAC data.\n", + " protac_labels (dict): The labels for the PROTAC data.\n", + " \"\"\"\n", + " pca = PCA(n_components=2, random_state=42)\n", + " scaler = StandardScaler()\n", + " pca_data = pca.fit_transform(scaler.fit_transform(protac_data))\n", + "\n", + " # Plot PCA accordingly\n", + " labels_to_plot = [\n", + " active_col,\n", + " 'Active - OR',\n", + " 'Cell Line Identifier',\n", + " 'E3 Ligase',\n", + " 'Uniprot',\n", + " # 'Smiles',\n", + " 'Treatment Time (h)',\n", + " 'DC50 (nM)',\n", + " 'Dmax (%)',\n", + " ]\n", + " for label in labels_to_plot:\n", + " if label not in protac_labels:\n", + " continue\n", + " pca_embeddings = {\n", + " 'PCA 1': pca_data[:, 0],\n", + " 'PCA 2': pca_data[:, 1],\n", + " label: protac_labels[label],\n", + " }\n", + " pca_embeddings = pd.DataFrame(pca_embeddings).drop_duplicates()\n", + " # Scatter plot\n", + " with warnings.catch_warnings():\n", + " warnings.simplefilter(\"ignore\")\n", + " sns.scatterplot(data=pca_embeddings, x='PCA 1', y='PCA 2',\n", + " hue=label) #, palette=sns.color_palette('tab10'))\n", + " # Plot legend for active and e3 ligase only\n", + " if label in [active_col, 'E3 Ligase']:\n", + " plt.legend(title=f'{label}:')\n", + " else:\n", + " plt.legend().remove()\n", + " plt.title(f'PCA embedding coloring for \"{label}\"')\n", + " plt.grid(axis='both', alpha=0.5)\n", + " plt.show()\n", "\n", - "if RUN_DIMENSIONALITY_REDUCTION:\n", " plot_pca(protac_data, protac_labels)" ] }, @@ -1106,79 +1134,78 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 27, "metadata": {}, "outputs": [], "source": [ - "# Run PCA analysis on protac_data and protac_labels\n", - "import warnings\n", - "import seaborn as sns\n", - "import matplotlib.pyplot as plt\n", - "from mpl_toolkits.mplot3d import Axes3D\n", - "from sklearn.decomposition import PCA\n", - "\n", + "if RUN_DIMENSIONALITY_REDUCTION:\n", + " # Run PCA analysis on protac_data and protac_labels\n", + " import warnings\n", + " import seaborn as sns\n", + " import matplotlib.pyplot as plt\n", + " from mpl_toolkits.mplot3d import Axes3D\n", + " from sklearn.decomposition import PCA\n", "\n", - "def plot_pca_3d(protac_data, protac_labels):\n", - " \"\"\" Plot the PCA embeddings.\n", "\n", - " Args:\n", - " protac_data (np.ndarray): The PROTAC data.\n", - " protac_labels (dict): The labels for the PROTAC data.\n", - " \"\"\"\n", - " pca = PCA(n_components=3, random_state=42)\n", - " scaler = StandardScaler()\n", - " pca_data = pca.fit_transform(scaler.fit_transform(protac_data))\n", - "\n", - " # Plot PCA accordingly\n", - " labels_to_plot = [\n", - " active_col,\n", - " 'Cell Line Identifier',\n", - " 'E3 Ligase',\n", - " 'Uniprot',\n", - " # 'Smiles',\n", - " 'Treatment Time (h)',\n", - " ]\n", - " for label in labels_to_plot:\n", - " pca_embeddings = {\n", - " 'PCA 1': pca_data[:, 0],\n", - " 'PCA 2': pca_data[:, 1],\n", - " 'PCA 3': pca_data[:, 2],\n", - " label: protac_labels[label],\n", - " }\n", - " pca_embeddings = pd.DataFrame(pca_embeddings).drop_duplicates()\n", - " # Scatter plot\n", - " with warnings.catch_warnings():\n", - " warnings.simplefilter(\"ignore\")\n", - " # Plot 3D scatter\n", - " fig = plt.figure()\n", - " ax = fig.add_subplot(111, projection='3d')\n", - " for l in pd.Series(protac_labels[label]).unique():\n", - " ax.scatter(\n", - " pca_embeddings[pca_embeddings[label] == l]['PCA 1'],\n", - " pca_embeddings[pca_embeddings[label] == l]['PCA 2'],\n", - " pca_embeddings[pca_embeddings[label] == l]['PCA 3'],\n", - " label=l,\n", - " )\n", - "\n", - " # sns.scatterplot(data=pca_embeddings, x='PCA 1', y='PCA 2',\n", - " # hue=label) #, palette=sns.color_palette('tab10'))\n", - " # Plot legend for active and e3 ligase only\n", - " if label in [active_col, 'E3 Ligase']:\n", - " plt.legend(title=f'{label}:')\n", - " else:\n", - " plt.legend().remove()\n", - " plt.title(f'PCA embedding coloring for \"{label}\"')\n", - " plt.grid(axis='both', alpha=0.5)\n", - " plt.show()\n", + " def plot_pca_3d(protac_data, protac_labels):\n", + " \"\"\" Plot the PCA embeddings.\n", "\n", + " Args:\n", + " protac_data (np.ndarray): The PROTAC data.\n", + " protac_labels (dict): The labels for the PROTAC data.\n", + " \"\"\"\n", + " pca = PCA(n_components=3, random_state=42)\n", + " scaler = StandardScaler()\n", + " pca_data = pca.fit_transform(scaler.fit_transform(protac_data))\n", + "\n", + " # Plot PCA accordingly\n", + " labels_to_plot = [\n", + " active_col,\n", + " 'Cell Line Identifier',\n", + " 'E3 Ligase',\n", + " 'Uniprot',\n", + " # 'Smiles',\n", + " 'Treatment Time (h)',\n", + " ]\n", + " for label in labels_to_plot:\n", + " pca_embeddings = {\n", + " 'PCA 1': pca_data[:, 0],\n", + " 'PCA 2': pca_data[:, 1],\n", + " 'PCA 3': pca_data[:, 2],\n", + " label: protac_labels[label],\n", + " }\n", + " pca_embeddings = pd.DataFrame(pca_embeddings).drop_duplicates()\n", + " # Scatter plot\n", + " with warnings.catch_warnings():\n", + " warnings.simplefilter(\"ignore\")\n", + " # Plot 3D scatter\n", + " fig = plt.figure()\n", + " ax = fig.add_subplot(111, projection='3d')\n", + " for l in pd.Series(protac_labels[label]).unique():\n", + " ax.scatter(\n", + " pca_embeddings[pca_embeddings[label] == l]['PCA 1'],\n", + " pca_embeddings[pca_embeddings[label] == l]['PCA 2'],\n", + " pca_embeddings[pca_embeddings[label] == l]['PCA 3'],\n", + " label=l,\n", + " )\n", + "\n", + " # sns.scatterplot(data=pca_embeddings, x='PCA 1', y='PCA 2',\n", + " # hue=label) #, palette=sns.color_palette('tab10'))\n", + " # Plot legend for active and e3 ligase only\n", + " if label in [active_col, 'E3 Ligase']:\n", + " plt.legend(title=f'{label}:')\n", + " else:\n", + " plt.legend().remove()\n", + " plt.title(f'PCA embedding coloring for \"{label}\"')\n", + " plt.grid(axis='both', alpha=0.5)\n", + " plt.show()\n", "\n", - "if RUN_DIMENSIONALITY_REDUCTION:\n", " plot_pca_3d(protac_data, protac_labels)" ] }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 28, "metadata": {}, "outputs": [], "source": [ @@ -1212,7 +1239,7 @@ }, { "cell_type": "code", - "execution_count": 26, + "execution_count": 29, "metadata": {}, "outputs": [], "source": [ @@ -1228,7 +1255,7 @@ }, { "cell_type": "code", - "execution_count": 338, + "execution_count": 34, "metadata": {}, "outputs": [ { @@ -1516,7 +1543,7 @@ }, { "cell_type": "code", - "execution_count": 340, + "execution_count": 35, "metadata": {}, "outputs": [ { @@ -1541,53 +1568,45 @@ }, { "cell_type": "code", - "execution_count": 344, + "execution_count": 59, "metadata": {}, "outputs": [], "source": [ "# Import train_val_split\n", "from sklearn.model_selection import train_test_split\n", "\n", - "protac_ds = PROTAC_Dataset(\n", + "train_df, test_df = train_test_split(\n", " protac_df[protac_df[active_col].notna()],\n", + " test_size=0.2,\n", + " random_state=42,\n", + ")\n", + "train_ds = PROTAC_Dataset(\n", + " train_df,\n", " protein_embeddings,\n", " cell2embedding,\n", " smiles2fp,\n", + " active_label=active_col,\n", " use_smote=False,\n", ")\n", - "scaler = protac_ds.fit_scaling(use_single_scaler=True)\n", - "protac_ds.apply_scaling(scaler, use_single_scaler=True)\n", - "\n", - "train_df, test_df = train_test_split(protac_ds, test_size=0.2, random_state=42)" - ] - }, - { - "cell_type": "code", - "execution_count": 85, - "metadata": {}, - "outputs": [], - "source": [ - "# Get the X and y as numpy arrays\n", - "X_train = np.hstack([\n", - " np.array(train_df['Smiles'].tolist()),\n", - " np.array(train_df['Uniprot'].tolist()),\n", - " np.array(train_df['E3 Ligase Uniprot'].tolist()),\n", - " np.array(train_df['Cell Line Identifier'].tolist()),\n", - "])\n", - "y_train = train_df[active_col].values\n", + "scaler = train_ds.fit_scaling(use_single_scaler=True)\n", + "train_ds.apply_scaling(scaler, use_single_scaler=True)\n", + "test_ds = PROTAC_Dataset(\n", + " test_df,\n", + " protein_embeddings,\n", + " cell2embedding,\n", + " smiles2fp,\n", + " active_label=active_col,\n", + " use_smote=False,\n", + ")\n", + "test_ds.apply_scaling(scaler, use_single_scaler=True)\n", "\n", - "X_test = np.hstack([\n", - " np.array(test_df['Smiles'].tolist()),\n", - " np.array(test_df['Uniprot'].tolist()),\n", - " np.array(test_df['E3 Ligase Uniprot'].tolist()),\n", - " np.array(test_df['Cell Line Identifier'].tolist()),\n", - "])\n", - "y_test = test_df[active_col].values" + "X_train, y_train = train_ds.get_numpy_arrays()\n", + "X_test, y_test = test_ds.get_numpy_arrays()" ] }, { "cell_type": "code", - "execution_count": 86, + "execution_count": 60, "metadata": {}, "outputs": [ { @@ -1595,7 +1614,7 @@ "output_type": "stream", "text": [ "Accuracy: 74.4%\n", - "ROC-AUC score: 0.772\n" + "ROC-AUC score: 0.768\n" ] } ], @@ -1623,10 +1642,207 @@ "print(f'ROC-AUC score: {roc_auc:.3f}')" ] }, + { + "cell_type": "code", + "execution_count": 64, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "test_acc: 0.744\n", + "test_f1_score: 0.758\n", + "test_hp_metric: 0.744\n", + "test_opt_score: 1.502\n", + "test_precision: 0.726\n", + "test_recall: 0.793\n", + "test_roc_auc: 0.768\n" + ] + } + ], + "source": [ + "import torch\n", + "import torch.nn as nn\n", + "from torchmetrics import (\n", + " Accuracy,\n", + " AUROC,\n", + " Precision,\n", + " Recall,\n", + " F1Score,\n", + " MetricCollection,\n", + ")\n", + "\n", + "stages = ['train_metrics', 'val_metrics', 'test_metrics']\n", + "metrics = nn.ModuleDict({s: MetricCollection({\n", + " 'acc': Accuracy(task='binary'),\n", + " 'roc_auc': AUROC(task='binary'),\n", + " 'precision': Precision(task='binary'),\n", + " 'recall': Recall(task='binary'),\n", + " 'f1_score': F1Score(task='binary'),\n", + " 'opt_score': Accuracy(task='binary') + F1Score(task='binary'),\n", + " 'hp_metric': Accuracy(task='binary'),\n", + "}, prefix=s.replace('metrics', '')) for s in stages})\n", + "\n", + "y_pred = torch.tensor(logreg.predict_proba(X_test)[:, 1])\n", + "y_true = torch.tensor(y_test)\n", + "metrics['test_metrics'].update(y_pred, y_true)\n", + "# Print the metrics\n", + "for k, v in metrics['test_metrics'].compute().items():\n", + " print(f'{k}: {v:.3f}')" + ] + }, + { + "cell_type": "code", + "execution_count": 85, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "train_acc: 1.000\n", + "train_f1_score: 1.000\n", + "train_hp_metric: 1.000\n", + "train_opt_score: 2.000\n", + "train_precision: 1.000\n", + "train_recall: 1.000\n", + "train_roc_auc: 1.000\n", + "val_acc: 0.744\n", + "val_f1_score: 0.758\n", + "val_hp_metric: 0.744\n", + "val_opt_score: 1.502\n", + "val_precision: 0.726\n", + "val_recall: 0.793\n", + "val_roc_auc: 0.768\n" + ] + } + ], + "source": [ + "from typing import Literal, List, Tuple, Optional\n", + "from sklearn.base import ClassifierMixin\n", + "\n", + "# Generic function to fit and evaluate a classifier model (given as argument),\n", + "# on train and val sets (and optionally a test set) given as dataframes\n", + "def train_sklearn_model(\n", + " clf: ClassifierMixin,\n", + " train_df: pd.DataFrame,\n", + " val_df: pd.DataFrame,\n", + " test_df: Optional[pd.DataFrame] = None,\n", + " active_label: str = 'Active',\n", + " use_single_scaler: bool = True,\n", + ") -> Tuple[ClassifierMixin, nn.ModuleDict]:\n", + " \"\"\" Train a classifier model on train and val sets and evaluate it on a test set.\n", + "\n", + " Args:\n", + " clf: The classifier model to train and evaluate.\n", + " train_df (pd.DataFrame): The training set.\n", + " val_df (pd.DataFrame): The validation set.\n", + " test_df (Optional[pd.DataFrame]): The test set.\n", + "\n", + " Returns:\n", + " Tuple[ClassifierMixin, nn.ModuleDict]: The trained model and the metrics.\n", + " \"\"\"\n", + " # Initialize the datasets\n", + " train_ds = PROTAC_Dataset(\n", + " train_df,\n", + " protein_embeddings,\n", + " cell2embedding,\n", + " smiles2fp,\n", + " active_label=active_label,\n", + " use_smote=False,\n", + " )\n", + " scaler = train_ds.fit_scaling(use_single_scaler=use_single_scaler)\n", + " train_ds.apply_scaling(scaler, use_single_scaler=use_single_scaler)\n", + " val_ds = PROTAC_Dataset(\n", + " val_df,\n", + " protein_embeddings,\n", + " cell2embedding,\n", + " smiles2fp,\n", + " active_label=active_label,\n", + " use_smote=False,\n", + " )\n", + " val_ds.apply_scaling(scaler, use_single_scaler=use_single_scaler)\n", + " if test_df is not None:\n", + " test_ds = PROTAC_Dataset(\n", + " test_df,\n", + " protein_embeddings,\n", + " cell2embedding,\n", + " smiles2fp,\n", + " active_label=active_label,\n", + " use_smote=False,\n", + " )\n", + " test_ds.apply_scaling(scaler, use_single_scaler=use_single_scaler)\n", + "\n", + " # Get the numpy arrays\n", + " X_train, y_train = train_ds.get_numpy_arrays()\n", + " X_val, y_val = val_ds.get_numpy_arrays()\n", + " if test_df is not None:\n", + " X_test, y_test = test_ds.get_numpy_arrays()\n", + "\n", + " # Train the model\n", + " clf.fit(X_train, y_train)\n", + " # Define the metrics as a module dict\n", + " stages = ['train_metrics', 'val_metrics', 'test_metrics']\n", + " metrics = nn.ModuleDict({s: MetricCollection({\n", + " 'acc': Accuracy(task='binary'),\n", + " 'roc_auc': AUROC(task='binary'),\n", + " 'precision': Precision(task='binary'),\n", + " 'recall': Recall(task='binary'),\n", + " 'f1_score': F1Score(task='binary'),\n", + " 'opt_score': Accuracy(task='binary') + F1Score(task='binary'),\n", + " 'hp_metric': Accuracy(task='binary'),\n", + " }, prefix=s.replace('metrics', '')) for s in stages})\n", + "\n", + " # Get the predictions\n", + " metrics_out = {}\n", + "\n", + " y_pred = torch.tensor(clf.predict_proba(X_train)[:, 1])\n", + " y_true = torch.tensor(y_train)\n", + " metrics['train_metrics'].update(y_pred, y_true)\n", + " metrics_out.update(metrics['train_metrics'].compute())\n", + "\n", + " y_pred = torch.tensor(clf.predict_proba(X_val)[:, 1])\n", + " y_true = torch.tensor(y_val)\n", + " metrics['val_metrics'].update(y_pred, y_true)\n", + " metrics_out.update(metrics['val_metrics'].compute())\n", + "\n", + " if test_df is not None:\n", + " y_pred = torch.tensor(clf.predict_proba(X_test)[:, 1])\n", + " y_true = torch.tensor(y_test)\n", + " metrics['test_metrics'].update(y_pred, y_true)\n", + " metrics_out.update(metrics['test_metrics'].compute())\n", + "\n", + " return clf, metrics_out\n", + "\n", + "# Train the logistic regression model\n", + "logreg = LogisticRegression(\n", + " penalty=None, #'l2',\n", + " max_iter=2000,\n", + " solver='lbfgs',\n", + " # dual=True, # True when n_features > n_samples\n", + " # C=0.05,\n", + " # tol=1e-5,\n", + " random_state=42,\n", + " # n_jobs=-1,\n", + ")\n", + "logreg, metrics = train_sklearn_model(logreg, train_df, test_df, active_label=active_col)\n", + "\n", + "for k, v in metrics.items():\n", + " print(f'{k}: {v:.3f}')" + ] + }, { "cell_type": "code", "execution_count": null, "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 39, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -1662,7 +1878,7 @@ }, { "cell_type": "code", - "execution_count": 110, + "execution_count": 40, "metadata": {}, "outputs": [], "source": [ @@ -1675,7 +1891,7 @@ }, { "cell_type": "code", - "execution_count": 136, + "execution_count": 41, "metadata": {}, "outputs": [], "source": [ @@ -1685,7 +1901,7 @@ }, { "cell_type": "code", - "execution_count": 200, + "execution_count": 42, "metadata": {}, "outputs": [ { @@ -1705,7 +1921,7 @@ "Name: Dmax (%), Length: 812, dtype: float64" ] }, - "execution_count": 200, + "execution_count": 42, "metadata": {}, "output_type": "execute_result" } @@ -1716,7 +1932,7 @@ }, { "cell_type": "code", - "execution_count": 329, + "execution_count": 47, "metadata": {}, "outputs": [ { @@ -1730,14 +1946,15 @@ ] }, { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" + "ename": "NameError", + "evalue": "name 'sns' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[47], line 88\u001b[0m\n\u001b[1;32m 85\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mNumber of training points: \u001b[39m\u001b[38;5;132;01m{\u001b[39;00m\u001b[38;5;28mlen\u001b[39m(y_train)\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m (after resampling)\u001b[39m\u001b[38;5;124m'\u001b[39m)\n\u001b[1;32m 87\u001b[0m \u001b[38;5;66;03m# Plot y_train\u001b[39;00m\n\u001b[0;32m---> 88\u001b[0m \u001b[43msns\u001b[49m\u001b[38;5;241m.\u001b[39mhistplot(y_train, kde\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mTrue\u001b[39;00m)\n\u001b[1;32m 89\u001b[0m plt\u001b[38;5;241m.\u001b[39mtitle(\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mDmax (\u001b[39m\u001b[38;5;124m%\u001b[39m\u001b[38;5;124m) distribution\u001b[39m\u001b[38;5;124m'\u001b[39m)\n\u001b[1;32m 90\u001b[0m plt\u001b[38;5;241m.\u001b[39mxlabel(\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mDmax (\u001b[39m\u001b[38;5;124m%\u001b[39m\u001b[38;5;124m)\u001b[39m\u001b[38;5;124m'\u001b[39m)\n", + "\u001b[0;31mNameError\u001b[0m: name 'sns' is not defined" + ] } ], "source": [ @@ -1838,25 +2055,15 @@ }, { "cell_type": "code", - "execution_count": 335, + "execution_count": 45, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "R^2 score: 0.948\n" + "R^2 score: 0.953\n" ] - }, - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAi8AAAGiCAYAAAAvEibfAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjYuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8o6BhiAAAACXBIWXMAAA9hAAAPYQGoP6dpAABDkUlEQVR4nO3de3xU9b3v//dcksk9IcRckAABIgIK2tAqtAhopWDL1ko9WvtQ2a22qNRiDr9W1Fbo3kp3H9bNtl7xAlrq0Z4iVluqso8GbcFuVFJREAlGgpAYICH3zGTWrN8fazJJSAgJZEi+5PV8PBYz6zJrvpNPyLznu75rjcu2bVsAAACGcPd3AwAAAHqD8AIAAIxCeAEAAEYhvAAAAKMQXgAAgFEILwAAwCiEFwAAYBTCCwAAMArhBQAAGIXwAgAAjBLV8LJixQp9+ctfVnJysjIzM3XFFVdo165dx33cpk2bVFBQoLi4OI0ePVqPPfZYNJsJAAAMEtXwsmnTJt1666165513tHHjRgWDQc2ePVsNDQ3HfExpaakuu+wyTZ8+Xdu2bdOdd96p2267TevWrYtmUwEAgCFcp/KLGQ8ePKjMzExt2rRJF110UZfb/OxnP9PLL7+snTt3RpYtXLhQ//znP7Vly5ZT1VQAADBAeU/lk9XU1EiS0tPTj7nNli1bNHv27A7LvvGNb+ipp55SS0uLYmJiOqzz+/3y+/2R+VAopKqqKg0dOlQul6sPWw8AAKLFtm3V1dVp2LBhcru7PzB0ysKLbdsqLCzU1772NZ1zzjnH3K6iokJZWVkdlmVlZSkYDOrQoUPKycnpsG7FihVavnx5VNoMAABOrX379mn48OHdbnPKwsuiRYv0wQcf6G9/+9txtz26x6T1yFZXPSlLly5VYWFhZL6mpkYjRozQZ599ppSUlJNsdUeWZenTTz/V6NGj5fF4+nTf6FvUyizUyxzUyhym1aq2tlajRo1ScnLycbc9JeHlxz/+sV5++WW99dZbx01T2dnZqqio6LCssrJSXq9XQ4cO7bS9z+eTz+frtHzIkCFRCS8pKSkaMmSIEb8Igxm1Mgv1Mge1ModptWptY0+GfET1bCPbtrVo0SK9+OKLeuONN5SXl3fcx0ydOlUbN27ssOz111/XlClTOo13AQAAg09Uw8utt96qtWvX6rnnnlNycrIqKipUUVGhpqamyDZLly7V9ddfH5lfuHCh9u7dq8LCQu3cuVNPP/20nnrqKS1ZsiSaTQUAAIaIanh59NFHVVNTo5kzZyonJycyvfDCC5FtysvLVVZWFpnPy8vThg0bVFRUpPPOO0//9m//pgcffFDz58+PZlMBAIAhojrmpSeXkFmzZk2nZTNmzND7778fhRYBAHDybNtWMBiUZVn93ZRjsixLoVBIzc3NA2bMi8fjkdfrPelLmZzS67wAAGC6QCCg8vJyNTY29ndTutUasPbu3TugrnuWkJCgnJwcxcbGnvA+CC8AAPRQKBRSaWmpPB6Phg0bptjY2AEVDNqzbVt+v18+n29AtNG2bQUCAR08eFClpaXKz88/7sXojoXwAgBADwUCAYVCIeXm5iohIaG/m9Ot1qEbcXFxAyK8SFJ8fLxiYmK0d+9eBQIBxcXFndB+ojpgFwCA09GJ9higb352/PQBAIBRCC8AAMAohBcAAAaBmTNnavHixf3djD5BeAEAAEYhvAAAAKMQXgAAOAm2basxEOyXqSdXsu9KdXW1rr/+eg0ZMkQJCQmaO3eudu/eHVm/d+9ezZs3T0OGDFFiYqImTpyoDRs2RB77ve99T2eccYbi4+OVn5+v1atX98nPsqe4zgsAACehqcXShF+81i/PveOX31BCbO/fyhcsWKDdu3fr5ZdfVkpKin72s5/psssu044dOxQTE6Nbb71VgUBAb731lhITE7Vjxw4lJSVJkn7+859rx44d+utf/6qMjAyVlJR0+MLlU4HwAgDAINIaWv7+979r2rRpkqTf//73ys3N1UsvvaSrrrpKZWVlmj9/vs4991xJ0ujRoyOPLysr0/nnn68pU6ZIkkaNGnXKXwPhBQCAkxAf49GOX36j3567t3bu3Cmv16sLLrggsmzo0KEaN26cdu7cKUm67bbbdPPNN+v111/X17/+dc2fP1+TJk2SJN18882aP3++3n//fc2ePVtXXHFFJASdKox5AQDgJLhcLiXEevtlOpHL/h9rnIxt25H93Xjjjfr000913XXXafv27ZoyZYp++9vfSpLmzp2rvXv3avHixTpw4IAuueQSLVmy5MR/gCeA8AIAwCAyYcIEBYNB/eMf/4gsO3z4sD755BONHz8+siw3N1cLFy7Uiy++qP/9v/+3nnjiici6M844QwsWLNDatWu1cuVKrVq16pS+Bg4bAQAwiOTn5+vyyy/XTTfdpMcff1zJycm64447dOaZZ+ryyy+XJC1evFhz587VWWedperqar3xxhuRYPOLX/xCBQUFmjhxovx+v/785z93CD2nAj0vAAAMMqtXr1ZBQYG+9a1vaerUqbJtWxs2bFBMTIwkybIs3XrrrRo/frzmzJmjcePG6ZFHHpEkxcbGaunSpZo0aZIuuugieTwePf/886e0/fS8AAAwCBQVFUXuDxkyRM8+++wxt20d39KVu+++W3fffXdfNq3X6HkBAABGIbwAAACjEF4AAIBRCC8AAMAohBcAAGAUwgsAADAK4QUAABiF8AIAAIxCeAEAAEYhvAAAgE4KCwvlcrl05ZVXyrKs/m5OB4QXAAAGgQULFsjlcsnlcsnr9WrEiBG6+eabVV1d3Wnbe++9V0888YQef/xxbdmyRT/60Y86bVNUVKTLL79cOTk5SkxM1Hnnnaff//73p+KlEF4AABgs5syZo/Lycn322Wd68skn9corr+iWW27psM2qVav0m9/8Rhs3btQPf/hDvfXWW9q4caN+9rOfddhu8+bNmjRpktatW6cPPvhA3//+93X99dfrlVdeifrr4IsZAQA4GbYttTT2z3PHJEguV4839/l8ys7OliQNHz5cV199tdasWRNZ/8c//lH33HOP3njjDZ133nmSpPz8fL399tu65JJLNHToUP30pz+VJN15550d9n3bbbfptdde0/r16zVv3ryTe13HQXgBAOBktDRK9w3rn+e+84AUm3hCD/3000/16quvKiYmJrLsO9/5jr7zne902nbEiBHavXv3cfdZU1Oj8ePHn1B7eoPwAgDAIPHnP/9ZSUlJsixLzc3NkqQHHnigT/b9xz/+UVu3btXjjz/eJ/vrDuEFAICTEZPg9ID013P3wqxZs/Too4+qsbFRTz75pD755BP9+Mc/PulmFBUVacGCBXriiSc0ceLEk97f8RBeAAA4GS7XCR+6OdUSExM1duxYSdKDDz6oWbNmafny5fq3f/u3E97npk2bNG/ePD3wwAO6/vrr+6qp3Yrq2UZvvfWW5s2bp2HDhsnlcumll17qdvuioqLIaVztp48//jiazQQAYFC65557dP/99+vAgRPrOSoqKtI3v/lN/epXv9IPf/jDPm7dsUU1vDQ0NGjy5Ml66KGHevW4Xbt2qby8PDLl5+dHqYUAAAxeM2fO1MSJE3Xffff1+rGtweW2227T/PnzVVFRoYqKClVVVUWhpR1FNbzMnTtX//7v/64rr7yyV4/LzMxUdnZ2ZPJ4PFFqIQAAg1thYaGeeOIJ7du3r1ePW7NmjRobG7VixQrl5OREpt6+55+IATnm5fzzz1dzc7MmTJigu+++W7NmzTrmtn6/X36/PzJfW1srSbIsq88vZ2xZlkKh0IC7TDI6o1ZmoV7mGOy1sixLtm1HpoGstX2tt6tXr+4w3+q73/2uvvvd73a5rjurV6+O7PNYz32sdbZtd3qf7s3v1IAKLzk5OVq1apUKCgrk9/v1u9/9TpdccomKiop00UUXdfmYFStWaPny5Z2W79mzR0lJSX3avlAopKqqKpWUlMjt5uLEAxm1Mgv1Msdgr1UoFFIwGOzwoXkgCwaD/d2ETvx+v4LBoPbu3dvhd6i+vr7H+3DZpyg6ulwurV+/XldccUWvHjdv3jy5XC69/PLLXa7vquclNzdXVVVVSklJOZkmd2JZlkpKSjR27FgOZQ1w1Mos1Mscg71Wzc3N2rt3r/Ly8hQXF9ffzemWbdvy+/3y+Xxy9eIqvNHW3Nys0tJSjRw5ssPPsLa2Vunp6aqpqTnu+/eA6nnpyoUXXqi1a9cec73P55PP5+u03OPxROU/ltvtjtq+0beolVmolzkGc608Hk+Hs2FNMNDa2tqeo3+HevP7NOD7/LZt26acnJz+bgYAABggotrzUl9fr5KSksh8aWmpiouLlZ6erhEjRmjp0qXav3+/nn32WUnSypUrNWrUKE2cOFGBQEBr167VunXrtG7dumg2EwCAXhnog3UHsr742UU1vLz77rsdzhQqLCyUJN1www1as2aNysvLVVZWFlkfCAS0ZMkS7d+/X/Hx8Zo4caL+8pe/6LLLLotmMwEA6JHWLzFsbGxUfHx8P7fGTI2Nzjdwt/9CyN6KaniZOXNmtwmr/ddwS9JPf/rTyFdtAwAw0Hg8HqWlpamyslKSlJCQMKDGk7TXOmBX0oBoo23bamxsVGVlpdLS0k5qzNSAH7ALAMBAkp2dLUmRADNQ2batYDAor9c7IMJLq7S0tMjP8EQRXgAA6AWXy6WcnBxlZmaqpaWlv5tzTJZlae/evRo5cuSAOTMsJiamT9pCeAEA4AQM9NPFLcuS2+1WXFzcgG7niRjwp0oDAAC0R3gBAABGIbwAAACjEF4AAIBRCC8AAMAohBcAAGAUwgsAADAK4QUAABiF8AIAAIxCeAEAAEYhvAAAAKMQXgAAgFEILwAAwCiEFwAAYBTCCwAAMArhBQAAGIXwAgAAjEJ4AQAARiG8AAAAoxBeAACAUQgvAADAKIQXAABgFMILAAAwCuEFAAAYhfACAACMQngBAABGIbwAAACjEF4AAIBRCC8AAMAohBcAAGAUwgsAADAK4QUAABglquHlrbfe0rx58zRs2DC5XC699NJLx33Mpk2bVFBQoLi4OI0ePVqPPfZYNJsIAAAME9Xw0tDQoMmTJ+uhhx7q0falpaW67LLLNH36dG3btk133nmnbrvtNq1bty6azQQAAAbxRnPnc+fO1dy5c3u8/WOPPaYRI0Zo5cqVkqTx48fr3Xff1f3336/58+dHqZUAAMAkUQ0vvbVlyxbNnj27w7JvfOMbeuqpp9TS0qKYmJhOj/H7/fL7/ZH52tpaSZJlWbIsq0/bZ1mWQqFQn+8XfY9amYV6mYNamcO0WvWmnQMqvFRUVCgrK6vDsqysLAWDQR06dEg5OTmdHrNixQotX7680/I9e/YoKSmpT9sXCoVUVVWlkpISud2MdR7IqJVZqJc5qJU5TKtVfX19j7cdUOFFklwuV4d527a7XN5q6dKlKiwsjMzX1tYqNzdXY8aMUUpKSp+2zbIslZSUaOzYsfJ4PH26b/QtamUW6mUOamUO02rVeuSkJwZUeMnOzlZFRUWHZZWVlfJ6vRo6dGiXj/H5fPL5fJ2WezyeqBTL7XZHbd/oW9TKLNTLHNTKHCbVqjdtHFD9SFOnTtXGjRs7LHv99dc1ZcqULse7AACAwSeq4aW+vl7FxcUqLi6W5JwKXVxcrLKyMknOIZ/rr78+sv3ChQu1d+9eFRYWaufOnXr66af11FNPacmSJdFsJgAAMEhUDxu9++67mjVrVmS+dWzKDTfcoDVr1qi8vDwSZCQpLy9PGzZs0O23366HH35Yw4YN04MPPshp0gAAICKq4WXmzJmRAbddWbNmTadlM2bM0Pvvvx/FVgEAAJMNqDEvAAAAx0N4AQAARiG8AAAAoxBeAACAUQgvAADAKIQXAABgFMILAAAwCuEFAAAYhfACAACMQngBAABGierXAwAABplQSKr6VNr/nlReLMUkSFkTpexzpfTRktvT3y08cUG/VHtAajjkvI6YBCkmTvLGSzHhyRPT363snm1LzTXOa2g4KDVUhm8PSXYoXKtJ0pBRksvV3609JsIL0B9CISnYLLU0ScEmSS4pOUdyG94ZatvSoU+kvX+X9m6R/LVSUpYzJWdJSdlScraUlOks8/r6u8WDW8Mhaecr0o6XpIoPpdTh0tCxbVPGWCl9jBSXcux91FU4QSUybZP8NV1v642XMse3hZmsic4UP6Tr7a0WqemI1HxEaqp27jdVS4E653etvQ7z7e673JI3zgkWXp/TBq+v3XxcePI5+67dL9WWOyGldr9UVx5edkBqPHzcH6nc3nZhJk7y+MIhwNXNrZxbt8d5fGQ6xrzL47wuqV3AaBc0wstctq2cmmq5321pF1YOSlbg+K8jLtUJMdmTpJzJUs4kaWi+5BkYsWFgtAI4nTQckj58Udr9mvPHNtgstTRKLeHbYLMzHS0mUTpjnPPHPXO8dMZ4KfNsKeXM7j8BhUJS7efS4T1S1R7p8KfObfVnzh+6hKFS4hnhKXw/ISM8n+FMvpQT+5QVCkmVH0l7N0uf/c25bTzU88fHD5GSsuVOytSwoEeunVmSL1mKTQxPSe1uw/e9PueTY1N129RYFb5f1XG+pdH5I+/yOMHQ5XHeAFpv299PHy1NuEI6+7Jjv5n2xpF90oH3pZDVtqybNxq5PM6bXUxCuzfbuLZP9N7wp/qT/TTcPrCUvi3Z7drXeMjpLTlaUlY40IyRa8hopR86KHfxXunANueN/WjeOCnnPGnY+U4NvvhQ+mKHE9QPvO9M7aUMd373Qy3hOta0hZSBxhsnJWY6P7eWpnYfQMJCQafdA6Dtbkmpx1rpSwn//z+jbQq1SBXbpcqdzv+xz952plbeOCnrHCfIZE+SJl/j/G72A5fd3dc+G6i2tlapqamqqalRSko3nxZOgGVZ2r17t/Lz8+XxGNz1OQic8loFGqVdG6QP/iCV/HfHN4Tj8cQ63bWhYNfrfSnSGWc7QeaM8c4b3OE9Ttf84XBIsfwn135PrBNyEjKkhPTw/aHOH7eEoe2WZThd52Wbpc/+7tw2H/Up2xsnDf+yNPKrTm9LfaXz6by+UqqvkOq+kOq/cP5QDkTuGGnsJdLEb0vj5jqfQHvCapH2/Y8TWndvlCp39H3bXG4nxCRlSkPHOL0ikdvRUuqIrj8ZtwaWj9Y7IbP972f2JGniFVLeDKcuh0uc6VD4tqHy+G06Y7x05pekMwucKXN858MnIUuqKg0HmQ+lLz5yentqyo7/un2pUnyaEyrj05yA62rfS9kaAF2dl4WCzu9ssMm5bWk6aj78YcLyO//XUoa1m850ekRTzmxbFj+kc4C07bae1Jamjvctf7hXyG7XO2Qftcx2Oota/w5EJuuo+XbLOuwvvM/WtoTnQyFbhw4fVsaIcXInZ4XDSqZz213oCAakgx9LFR9I5R84txXbpUB92zbuGOnOA5I3tvva9UJv3r8JL71AeDGHFWzRno/e15iJBfJ4o9TBGLKcTyUf/EHa8XLHT1rDzpfOvUoaknfUp+mEzp+u3R7JCjph5OBO51NP5U7nj8fhkmOHmvbcMc4x6vZvZOmjnT9kDYecT9StXcYNh53bxkPOuvZ/kE5EbJKUe4E0cpo06mvOaz/e4SDbdj5Z11VI9V8oVFuuys/3KDM1Ue5goxRokPx1zm1kqndug81OoIgf0jYlpLebT29bFpPgvCHYIadetnXUbXi5FZDKtjhv7u1DhydWGntpOMjMcd4026uvdILK7telPW92PFzicjvBIDap9UW3vfa2H0Tb3VCwY+9c+zdB9fDPtDtGGjKyLdQkZTrtOjqw5Ex2epkmXO5s153mGickH94jHS5R6NAnqq+rVdJZF8md+2XnNfqSut9Hd5qOOD/zQ7udekVCSnjypZyaQxW2PaDHeJyIPn3Pah3LVPFPJ9D466RvPdA3DQ0jvBBezBAKSZ++KX3wgvOHI/cr0ogLpcwJJzaor/oz6dNN0qdFsks3ydV4WHZcqlyZE5x9ZoVvMyc4fyBPVMWH0gfPS9v/6BwPb5U2Qpp0tXTu/5LOOOvE999eMOAEmModTpip3Om80UY+cY92blOGn/gf+JamcMA53HmKLK8K34YH9Q3/ijTqq05gyZ580m8uA+r/VuVO6aOXpI9edMbvtPLGSfmXSuO+KVWXOoHlwLaOj00YKo39upQ/WxpzsROgTpZtt/UUtIab2gPhQ4Tte+BKuz4c2ao1sEy8wvm9OUEDqlbolmm16s37N2NecOrVV0rb1krvP+MEjlbb/+Dc+lKk4VOk3AulERdIZ07p+pNdw2GpdJMzfVrUYV+RkQXNNc4n6rItHR+bcmY4yIQHDyZlOp8kmmudT5r+2qPuh28bDjvjS1rFpTmfyidf4/Q+9PUnN2+sE7qyJvTtftuLiZfScp0JbWOOZt7hhMaP1jtjmKr2OIdedr7Scfth5zthJX+2c7+vz6ZxucK9dXFSa0//0DFS3vSO24VCUt2BdmOf9jjjUXImOz0sJxFYgIGG8IJTIxRyQsZ7q6WP/9J2KMSXKk2+2vnEWvaO9PlWJyTsecOZJGcgY/Y5TpjJmewcWvl0k3Mctj231xlrkTdD1qiLVFIfr7FDvfIc+tg5vl65w/lUXbMvfPbAfqlkY+9fiydWOmuO08uSfylnzJyuXK62s2Fm3eWM0/jwRae3MG2kE1bGft0Z1zMQuN3O2UKpw6XRM/q7NUBUEV4QXfUHpeK10nvPON3arYZ/WSr4V6fXIjahbXnIcoLGvn84YabsHaeno/yfznS0zInS6JnOH+uR09rGJFiW7N27pax8adikjo9prnFCTGug+WKHM/4iLtU5JdSX0sX98ORLcc6KOJnDTjCPy+Wc2pt9rqR7+rs1wKBHeBnsWpqk6r3OOAavz5k8PudwhTfO6WXo6lCIbbcbVFnv3Ebu1zu9J3v/Lu38c9tZJb4UadL/kgoWhN8EuuD2OKfh5UySvnKTs6zmcyfE7PuHM+J96Bgpb6aUd9GJfeqNS3XG1oy4sPePBQD0O8LLYGC1SEfKwqdA7mk7FfLwno7jN47F0xpqYp1DMy2NTlDp6RkQZxY4vSznXOlcp6O3UodL537HmQAAgx7h5XR0pEwqfk7a/37bxcq6O93Wl+pckyHod65JcPTVFy3/sa8j4nJLscnO4RpfUvgCY+Hb1OHS5O86vSgAAPQRwsvpwgo6F8d6b41z3Ymje0W88c7hlqFj2i79nR6+n5De8dBQKOQEGMsfPkUzHGiCzU4IiklsCysxCafdtREAAAMb4cV0R8qk938nbftdx2uO5F0kjf8XKeMsJ6D05ntz3G7JHT41EwCAAYbwYqJj9bIkDJXO+54zIPZ4V80EAMBQhBeTVO91Lu7WVS9LwQLp7G9xzREAwGmP8DLQNVY5lyn/4P9K+95pW04vCwBgkCK8DEQtTdKuv4a/oXhjuzOFXOFelhvoZQEADFqEl4EiZDmXz//g/zrfndL+G4qzz3UuRX/OfOcr2QEAGMQIL/3JtqX97znfl/LhOqm+om1d6ghp0lXONxRnnt1/bQQAYIAhvJxqoZDz5YM7XpJ2vNz1NxRPutr5huKentoMAMAgQng5FUKW8908O/4k7Xy545lCsUnOt9Oee5XzDbXe2P5rJwAABiC89JIV6uH3+VhB54sJd/zJGcPSUNm2zpcijZsrTbhcGnOxFBMfncYCAHAaIrz0UFVDQL9+dac+/vyw/nhWfvcbH/xEWnulVLOvbVlcqjTum9LEK6TRMzlTCACAE0R46aGmFkvrtx2QPxjS6zu+0GWTzux6w0CD9IfrneASP8Q5pXnCFc4pzhwSAgDgpDEitIfOTIvXTdPzJEm/enWX/EGr6w03/H/SwZ1SUpZ06/9Ilz8k5TOWBQCAvnJKwssjjzyivLw8xcXFqaCgQG+//fYxty0qKpLL5eo0ffzxx6eiqd364fQ8DU3wqKyqSWv+/lnnDbatlYp/L7nc0vynpKTMU95GAABOd1EPLy+88IIWL16su+66S9u2bdP06dM1d+5clZWVdfu4Xbt2qby8PDLl5x9nnMkpkOjzasGX0iVJv32jRAfr/G0rv9gh/WWJc3/WnVLe9H5oIQAAp7+oj3l54IEH9IMf/EA33nijJGnlypV67bXX9Oijj2rFihXHfFxmZqbS0tKOu3+/3y+/vy1E1NbWSpIsy5JlHePQzgmyLEuz8hL12qfN+vBAnX7z+se694pzpEC93H+4Xq5gk+wxFys0bbHUx8+N3rEsS6FQqM9/BxAd1Msc1MocptWqN+2MangJBAJ67733dMcdd3RYPnv2bG3evLnbx55//vlqbm7WhAkTdPfdd2vWrFldbrdixQotX7680/I9e/YoKSnpxBvfhVAopCPV1br+3CT99ECd/vDu57oo29ZXP7lPqYd3qyX+DH127k9llezp0+dF74VCIVVVVamkpERuLvY34FEvc1Arc5hWq/r6+h5vG9XwcujQIVmWpaysrA7Ls7KyVFFR0eVjcnJytGrVKhUUFMjv9+t3v/udLrnkEhUVFemiiy7qtP3SpUtVWFgYma+trVVubq7GjBmjlJSUPn09lmWppKREXxk7VkX7bW34sEIHtr6o1COvyXZ55L76GY3O/UqfPidOTGutxo4dK4/H09/NwXFQL3NQK3OYVqvWIyc9cUpOlXa5XB3mbdvutKzVuHHjNG7cuMj81KlTtW/fPt1///1dhhefzyefr/M1UzweT1SK5Xa75fF4tPSy8dr/8f/ouupHJJfkuuQX8oz6ap8/H05ca61M+E8L6mUSamUOk2rVmzZGtR8pIyNDHo+nUy9LZWVlp96Y7lx44YXavXt3XzfvpOQmBLU66SH5XC3a4pmiwAWL+rtJAAAMClENL7GxsSooKNDGjRs7LN+4caOmTZvW4/1s27ZNOTk5fd28E2fb0ss/Vnrz5ypXhm5uuEnPvtP92VMAAKBvRP2wUWFhoa677jpNmTJFU6dO1apVq1RWVqaFCxdKcsas7N+/X88++6wk52ykUaNGaeLEiQoEAlq7dq3WrVundevWRbupPeZ690nnW6HdXn14wUodedOtB//fbl35peFKT+RidAAARFPUw8vVV1+tw4cP65e//KXKy8t1zjnnaMOGDRo5cqQkqby8vMM1XwKBgJYsWaL9+/crPj5eEydO1F/+8hdddtll0W5qj8RV7ZTrv+92Zi79pS6+4Fsa//HftLO8Viv/+xP98vJz+reBAACc5ly2bffwa5LNUFtbq9TUVNXU1PT92Ub1h2U9+lXFNpQ731l09VrJ5dLmPYd07RP/kMft0qs/ma78rOQ+fV70nmVZ2r17t/Lz840YqDbYUS9zUCtzmFar3rx/D/wTvwcK25b75UWKbSiXnTZSuvxhKXzG1LQxGZo9IUtWyNa//2VnPzcUAIDTG+Glpw5sk3a/ppA7RqH5T0vxaR1W33nZeMV4XNr0yUG9uauyf9oIAMAgQHjpqTO/pND1r6jiy0ulYed3Wj0qI1ELpo2SJP37n3eoxQqd4gYCADA4EF56Y8SFqs375jFXL7o4X+mJsdpzsEHP/YNTpwEAiAbCSx9KjY9R4aVnSZL+878/0ZHGQD+3CACA0w/hpY9d8+VcnZWVpCONLfrFnz6SP2jGt3kCAGAKwksf83rcumfeREnSy/88oPmPblbpoYZ+bhUAAKcPwksUfHVshp68foqGJMTow/21+taDb2v9ts/7u1kAAJwWCC9R8vUJWfrrTy7SBXnpaghYuv2Ff6rwD8Vq8Af7u2kAABiN8BJF2alxeu6mC3X718+S2yW9+P5+zfvt3/Th/pr+bhoAAMYivESZx+3ST76er/9z04XKSY3Tp4cadOUjm7X676U6zb6ZAQCAU4LwcopcMHqoNtw2XZdOyFLACmn5Kzt007PvqrqB06kBAOgNwsspNCQxVquuK9Dyf5moWI9b/72zUnP/62298+nh/m4aAADG8PZ3AwYbl8ulG6aN0pRRQ/Tj/7NNnx5s0LVPvKMLRw/VzHFnaNa4TI3NTJIr/KWPAACgI8JLP5k4LFWvLPqa7nn5I/3xvc+1ec9hbd5zWPdt+FhnpsVr1tlnaOZZmZo2dqgSYikTAACteFfsR4k+r+6/arIWzRqrol2VenPXQW359LD2H2nS2nfKtPadMsV63LpgdLpmjcvUrLMzlZeR2N/NBgCgXxFeBoBRGYlakJGnBV/NU1PA0pZPD6lo10G98XGlPq9u0tu7D+nt3Yf0yz/v0PAh8frSiCGanJum83LTNHFYiuJiPP39EgAAOGUILwNMfKxHF5+dpYvPztLyf7G152CDinZVqmjXQf2j9LA+r27S59VNevmfByRJXrdL43NSNDk3VeflDtF5uakanZEkt5sxMwCA0xPhZQBzuVwam5mksZlJunH6aDX4g9pWdkTF+6pVvK9GxfuO6FC9X9v312j7/hqtfadMkpTs82pSbqomDU/TpDNTde7wVJ2ZFs8gYADAaYHwYpBEn1dfy8/Q1/IzJEm2betATbOKy47on58fUXHZEW3fX6M6f1B/Lzmsv5e0nYI9JCFG5w5P07lnpujcM9M0aXiqclLjCDQAAOMQXgzmcrl0Zlq8zkyL1zcn5UiSglZIn3xRr+J9R8I9Mkf0cXmdqhtb9NYnB/XWJwcjjx+aGKtzh6fq3DNTlZkSp2SfV4k+rxJ9HiX7YpTo8ygpzqskn1fxMR6CDgBgQCC8nGa8HrcmDEvRhGEpkWXNLZZ2VdQ5YeZz5xDTri/qdLghoKJdB1W062A3e3S4XU7PT0pcjEYOTdDoMxKVl5Gk0RmJGn1Gos5Mi5fXwzUPAQDRR3gZBOJiPJqcm6bJuWmRZc0tlnaW1+rD/TX66ECtqhsDqvcHVe+31OAPqr456NwGgrJtKWRLdc1B1TUHtf9Ikzbv6XhV4BiPSyOHJiovIzESaIYPSVByuOcmKc4JPj6vmx4cAMBJIbwMUnExHp0/YojOHzGk2+1CIVtNLU6gqfMHdaQxoNJDjSo9VK9PDzao9JAz+YMhlVTWq6Syvtv9ed2uyKGopHBPTlKcV/GxHsV5PYqPdSvO61FcjEdxMe7wbdt8fIxH6YmxykqJU0aST7FeensAYLAhvKBbbrcrPA7Gq8zwsoKR6R22CYVsHahp6hBm9hysV0VNsxN6mtt6cIIhW0caW3SksaVP2peeGKvMZJ8yU+KUmexTVopPmclxykiMkb+mWQkZTcpOSyDkAMBphPCCk+Z2uzR8SIKGD0nQRWed0eU2oZCtxhZL9c1B1TW3qC58aKre78w3Biw1t4TU3GK1m0JqDlpqClhqDjrrmgKWDtf7VVnnVzBkq6ohoKqGgD6uqOu6cRv2S2oLOVkpccpOiXNCTkqcssL30+Jj5fG45HG55HF3nLxul9zh5W6XOOwFAP2M8IJTwu12RQ4VZafGnfT+QiFb1Y0BVdb59UVtsyrr/DrYer/Wry/qmrX/cL2ONFsKWD0IOb3g87qVEOtRQqxzuCsh1qP4GE/nZbEeJftax/zEKMnn7TAGKDl823omV3OLpaqGgKobA6puaHFuG512H2lsiayzQrZS4mKUHOdVSnxMh/vJ4bFFyXFepcbHKC7GI1+MW7EeN+ONTqGgFVJVY0B1zUElx3mVFh9L7x/QhwgvMJLb7dLQJJ+GJvk0Piel03rLsrR7926NHTtWtf6Qvqhtbgs2tc36oq5ZX9T6VVnr3NY0tciybYVCtoIhu9vn9gdD8gdDqu6jQ19ulxTjccsfDPXJ/roT63XL53G3BZoYj2I9bsV63erpRZltSVbIbpva/dxC4fnWdR63W8lxzun3ibFOcGs9DJnk84RvvUqIcevgwVq9f2Sf5HIrZNuybVshWwqFb515W7YtuV0uuVzOrdsledwuuVyuyLw73Fvmdbvk8zqv1+d1xk35vB75vM54Kp83PB/jlsslBS3bmUIhBUO2WqxQeD68zLIVsEI60hjQobqADjX4ndt6f7vJCZn2Ub9GST6v0hJilJYQoyEJsUpLiNWQhBilxccoLSFWiT5Pp9drhTq+diuk8K2tQDCkFiukgOXctgSd9vqtkFrC64IhW8lxXqUnxio90aehibFKT4x1bpOc++kJsZwpCOMQXnBac7lc4T/csV2GnGOJvBmH3yha35iDIVv+8KGshoClxkBQTQFLjQErfBtUY4sVWdY60Ln1EFmHw2b+tjO5WoOL1+3SkPAbSlpCjNITnTe59ETnDW9IQqy8Hpdqm4OqbWpRXXNQtc0tx7zf3NIxEAWCIQWCIdX5+/TH3K1D9b15suOftm+K1ssLtNa5Plzzz6ub+rtpnaTGO6EqxuOW1+1ybj0uxbidW294eevUUF+vhHfrFbIlKyRZoZAs2/l/0z7QWl0Ez/bzrWGtNejFetyKi/UoPjxYPz48+Vrvhwf0x3jdClohtVhOYGsJ3w+0C26t60K28/+qw2Hgo249bueQcevXqrgi/0guOUG5dZHrqOXOstb77Ze1LXe7nP27wkHbHX4ut0vO87ab77Afl0sutYX19s8V43HJ63YrxuNWrLeL+163PLJV22yppqlFXm8oEu5b9x+ZD99a4cP7TeG/XY3hv2Otf+caApaaAkE1BCyFbFu3zBx7qn5FOyG8AF1wu12KjfL3Q9m2rcaApXp/UIFgSGkJzqGlvjy0Y9vOH/RAuLfIH2y9b0WWtQYaW933OLXXOgao9Y++p/0bQrt1LVZIDa2n3/uD7W4tNQTaLWtuUX19g5KTnO/lavvD2vGPrDv8s7Glo978ju6lcJYHLSds+oMh+Vuc190cvvWHx1Edq6Ot9U2t9Y3c6w6/gXtcGpIQq6FJscpI8oWndveTYzU00af0xFh53C6FQrZqm1tU3egcCjzS7rDgkcYWHWkKqLqxRU0Bq8PrdLvbfgbte5PcLud6TrEet2I8LsV6nTetmHbLYrzOfY/bpdom55Dj4fCh09bb1sOQti3VNLWopqm3PYndn1mIgeSzPt+jz+smvACDkcvVdiZXNJ/DOUziUXLUnuXktR7my8/Pl8dzar8lvcVyQozkHL5r/XTeVyHS7XYpLXyYKE+JfbLPvmKFbB0Jj6uqaWpRwAo5PY3hXov2h86skK2WUEiBFktfVFYqOytTXo+nyxDr3G8Lue5wt0H7cHZ0QJWcnkFngH54oH544H5Ti6WmdoP5A0HbCWnh0BbjdYWDW+vUts7lajvM2b4H1QqFIr1GwfB6W074lRTpDbI73D9qnW1H1ofa3Zec3qTW5ZHDgK3BOtQattt6oFrnW/dvy1Yo5Ny27qv1fuTQYWud2vU8tb/fYoU6Hb7sCY/bFR7D54zjS4iM4/MqMTyeLzHWK9u2+20cHeEFwKDW+iY3GHnajR3rKSdoBpSfP/KUB030jmVZ+njXJxo7dqxcbk+7Q3d2pPfSDrXNuyQl+JxxcAN9cD/hBQCA05TH7YxZ8pxmAf30ejUAAOC0R3gBAABGOSXh5ZFHHlFeXp7i4uJUUFCgt99+u9vtN23apIKCAsXFxWn06NF67LHHTkUzAQCAAaIeXl544QUtXrxYd911l7Zt26bp06dr7ty5Kisr63L70tJSXXbZZZo+fbq2bdumO++8U7fddpvWrVsX7aYCAAADRH3A7gMPPKAf/OAHuvHGGyVJK1eu1GuvvaZHH31UK1as6LT9Y489phEjRmjlypWSpPHjx+vdd9/V/fffr/nz53fa3u/3y+9vuwhWbW2tJGeUtWVZffpaLMtSKBTq8/2i71Ers1Avc1Arc5hWq960M6rhJRAI6L333tMdd9zRYfns2bO1efPmLh+zZcsWzZ49u8Oyb3zjG3rqqafU0tKimJiYDutWrFih5cuXd9rPnj17lJSUdJKvoKNQKKSqqiqVlJTI7Wa40EBGrcxCvcxBrcxhWq3q63t+4cOohpdDhw7JsixlZWV1WJ6VlaWKioouH1NRUdHl9sFgUIcOHVJOTk6HdUuXLlVhYWFkvra2Vrm5uRozZoxSUnp+OfiesCxLJSUlGjt2LNc3GOColVmolzmolTlMq1XrkZOeOCXXeTn6YjfHuypfV9t3tVySfD6ffL7OF1jyeDxRKZbb7Y7avtG3qJVZqJc5qJU5TKpVb9oY1X6kjIwMeTyeTr0slZWVnXpXWmVnZ3e5vdfr1dChQ6PWVgAAYIaohpfY2FgVFBRo48aNHZZv3LhR06ZN6/IxU6dO7bT966+/rilTpnQa7wIAAAafqI/gKSws1JNPPqmnn35aO3fu1O23366ysjItXLhQkjNm5frrr49sv3DhQu3du1eFhYXauXOnnn76aT311FNasmRJtJsKAAAMEPUxL1dffbUOHz6sX/7ylyovL9c555yjDRs2aOTIkZKk8vLyDtd8ycvL04YNG3T77bfr4Ycf1rBhw/Tggw92eZo0AAAYfE7JgN1bbrlFt9xyS5fr1qxZ02nZjBkz9P7770e5VQAAwEQD/8RvAACAdggvAADAKIQXAABgFMILAAAwCuEFAAAYhfACAACMQngBAABGIbwAAACjEF4AAIBRCC8AAMAohBcAAGAUwgsAADAK4QUAABiF8AIAAIxCeAEAAEYhvAAAAKMQXgAAgFEILwAAwCiEFwAAYBTCCwAAMArhBQAAGIXwAgAAjEJ4AQAARiG8AAAAoxBeAACAUQgvAADAKIQXAABgFMILAAAwCuEFAAAYhfACAACMQngBAABGIbwAAACjEF4AAIBRCC8AAMAohBcAAGCUqIaX6upqXXfddUpNTVVqaqquu+46HTlypNvHLFiwQC6Xq8N04YUXRrOZAADAIN5o7vzaa6/V559/rldffVWS9MMf/lDXXXedXnnllW4fN2fOHK1evToyHxsbG81mAgAAg0QtvOzcuVOvvvqq3nnnHV1wwQWSpCeeeEJTp07Vrl27NG7cuGM+1ufzKTs7O1pNAwAABotaeNmyZYtSU1MjwUWSLrzwQqWmpmrz5s3dhpeioiJlZmYqLS1NM2bM0L333qvMzMwut/X7/fL7/ZH52tpaSZJlWbIsq49ejSL7DIVCfb5f9D1qZRbqZQ5qZQ7TatWbdkYtvFRUVHQZODIzM1VRUXHMx82dO1dXXXWVRo4cqdLSUv385z/XxRdfrPfee08+n6/T9itWrNDy5cs7Ld+zZ4+SkpJO7kUcJRQKqaqqSiUlJXK7Ges8kFErs1Avc1Arc5hWq/r6+h5v2+vwsmzZsi7DQntbt26VJLlcrk7rbNvucnmrq6++OnL/nHPO0ZQpUzRy5Ej95S9/0ZVXXtlp+6VLl6qwsDAyX1tbq9zcXI0ZM0YpKSnHfT29YVmWSkpKNHbsWHk8nj7dN/oWtTIL9TIHtTKHabVqPXLSE70OL4sWLdI111zT7TajRo3SBx98oC+++KLTuoMHDyorK6vHz5eTk6ORI0dq9+7dXa73+Xxd9sh4PJ6oFMvtdkdt3+hb1Mos1Msc1MocJtWqN23sdXjJyMhQRkbGcbebOnWqampq9D//8z/6yle+Ikn6xz/+oZqaGk2bNq3Hz3f48GHt27dPOTk5vW0qAAA4DUXtINj48eM1Z84c3XTTTXrnnXf0zjvv6KabbtK3vvWtDoN1zz77bK1fv16Sc7xryZIl2rJliz777DMVFRVp3rx5ysjI0Le//e1oNRUAABgkqiN4fv/73+vcc8/V7NmzNXv2bE2aNEm/+93vOmyza9cu1dTUSHK6jLZv367LL79cZ511lm644QadddZZ2rJli5KTk6PZVAAAYIioXqQuPT1da9eu7XYb27Yj9+Pj4/Xaa69Fs0kAAMBwA//cKQAAgHYILwAAwCiEFwAAYBTCCwAAMArhBQAAGIXwAgAAjEJ4AQAARiG8AAAAoxBeAACAUQgvAADAKIQXAABgFMILAAAwCuEFAAAYhfACAACMQngBAABGIbwAAACjEF4AAIBRCC8AAMAohBcAAGAUwgsAADAK4QUAABiF8AIAAIxCeAEAAEYhvAAAAKMQXgAAgFEILwAAwCiEFwAAYBTCCwAAMArhBQAAGIXwAgAAjEJ4AQAARiG8AAAAoxBeAACAUQgvAADAKIQXAABglKiGl3vvvVfTpk1TQkKC0tLSevQY27a1bNkyDRs2TPHx8Zo5c6Y++uijaDYTAAAYJKrhJRAI6KqrrtLNN9/c48f8+te/1gMPPKCHHnpIW7duVXZ2ti699FLV1dVFsaUAAMAUUQ0vy5cv1+23365zzz23R9vbtq2VK1fqrrvu0pVXXqlzzjlHzzzzjBobG/Xcc89Fs6kAAMAQ3v5uQHulpaWqqKjQ7NmzI8t8Pp9mzJihzZs360c/+lGnx/j9fvn9/sh8bW2tJMmyLFmW1aftsyxLoVCoz/eLvketzEK9zEGtzGFarXrTzgEVXioqKiRJWVlZHZZnZWVp7969XT5mxYoVWr58eafle/bsUVJSUp+2LxQKqaqqSiUlJXK7Ges8kFErs1Avc1Arc5hWq/r6+h5v2+vwsmzZsi7DQntbt27VlClTervrCJfL1WHetu1Oy1otXbpUhYWFkfna2lrl5uZqzJgxSklJOeE2dMWyLJWUlGjs2LHyeDx9um/0LWplFuplDmplDtNq1XrkpCd6HV4WLVqka665ptttRo0a1dvdSpKys7MlOT0wOTk5keWVlZWdemNa+Xw++Xy+Tss9Hk9UiuV2u6O2b/QtamUW6mUOamUOk2rVmzb2OrxkZGQoIyOjtw/rkby8PGVnZ2vjxo06//zzJTlnLG3atEn/8R//EZXnBAAAZonqQbCysjIVFxerrKxMlmWpuLhYxcXFHY5rnX322Vq/fr0k53DR4sWLdd9992n9+vX68MMPtWDBAiUkJOjaa6+NZlMBAIAhojpg9xe/+IWeeeaZyHxrb8qbb76pmTNnSpJ27dqlmpqayDY//elP1dTUpFtuuUXV1dW64IIL9Prrrys5OTmaTQUAAIaIanhZs2aN1qxZ0+02tm13mHe5XFq2bJmWLVsWvYYBAABjDfxzpwAAANohvAAAAKMQXgAAgFEILwAAwCiEFwAAYBTCCwAAMArhBQAAGIXwAgAAjEJ4AQAARiG8AAAAoxBeAACAUQgvAADAKIQXAABgFMILAAAwCuEFAAAYhfACAACMQngBAABGIbwAAACjEF4AAIBRCC8AAMAohBcAAGAUwgsAADAK4QUAABiF8AIAAIxCeAEAAEYhvAAAAKMQXgAAgFEILwAAwCiEFwAAYBTCCwAAMArhBQAAGIXwAgAAjEJ4AQAARiG8AAAAoxBeAACAUaIaXu69915NmzZNCQkJSktL69FjFixYIJfL1WG68MILo9lMAABgkKiGl0AgoKuuuko333xzrx43Z84clZeXR6YNGzZEqYUAAMA03mjufPny5ZKkNWvW9OpxPp9P2dnZUWgRAAAwXVTDy4kqKipSZmam0tLSNGPGDN17773KzMzsclu/3y+/3x+Zr62tlSRZliXLsvq0XZZlKRQK9fl+0feolVmolzmolTlMq1Vv2jngwsvcuXN11VVXaeTIkSotLdXPf/5zXXzxxXrvvffk8/k6bb9ixYpID097e/bsUVJSUp+2LRQKqaqqSiUlJXK7Ges8kFErs1Avc1Arc5hWq/r6+h5v67Jt2+7NzpctW9ZlWGhv69atmjJlSmR+zZo1Wrx4sY4cOdKbp5IklZeXa+TIkXr++ed15ZVXdlrfVc9Lbm6uqqqqlJKS0uvn645lWSopKdHYsWPl8Xj6dN/oW9TKLNTLHNTKHKbVqra2Vunp6aqpqTnu+3eve14WLVqka665ptttRo0a1dvdHlNOTo5Gjhyp3bt3d7ne5/N12SPj8XiiUiy32x21faNvUSuzUC9zUCtzmFSr3rSx1+ElIyNDGRkZvX3YCTt8+LD27dunnJycU/acAABg4IrqQbCysjIVFxerrKxMlmWpuLhYxcXFHY5rnX322Vq/fr0k53jXkiVLtGXLFn322WcqKirSvHnzlJGRoW9/+9vRbCoAADBEVAfs/uIXv9AzzzwTmT///PMlSW+++aZmzpwpSdq1a5dqamokOV1G27dv17PPPqsjR44oJydHs2bN0gsvvKDk5ORoNhUAABgiquFlzZo1x73GS/vxwvHx8Xrttdei2SQAAGC4gX/uFAAAQDuEFwAAYBTCCwAAMArhBQAAGIXwAgAAjEJ4AQAARiG8AAAAoxBeAACAUQgvAADAKIQXAABgFMILAAAwCuEFAAAYhfACAACMQngBAABGIbwAAACjEF4AAIBRCC8AAMAohBcAAGAUwgsAADAK4QUAABiF8AIAAIxCeAEAAEYhvAAAAKMQXgAAgFEILwAAwCiEFwAAYBTCCwAAMArhBQAAGIXwAgAAjEJ4AQAARiG8AAAAoxBeAACAUQgvAADAKIQXAABgFMILAAAwCuEFAAAYJWrh5bPPPtMPfvAD5eXlKT4+XmPGjNE999yjQCDQ7eNs29ayZcs0bNgwxcfHa+bMmfroo4+i1UwAAGCYqIWXjz/+WKFQSI8//rg++ugj/ed//qcee+wx3Xnnnd0+7te//rUeeOABPfTQQ9q6dauys7N16aWXqq6uLlpNBQAABvFGa8dz5szRnDlzIvOjR4/Wrl279Oijj+r+++/v8jG2bWvlypW66667dOWVV0qSnnnmGWVlZem5557Tj370o06P8fv98vv9kfmamhpJUnV1tSzL6suXJMuyVFtbq+rqank8nj7dN/oWtTIL9TIHtTKHabWqra2V5GSB44laeOlKTU2N0tPTj7m+tLRUFRUVmj17dmSZz+fTjBkztHnz5i7Dy4oVK7R8+fJOy0eNGtUnbQYAAKdOXV2dUlNTu93mlIWXPXv26Le//a1+85vfHHObiooKSVJWVlaH5VlZWdq7d2+Xj1m6dKkKCwsj86FQSFVVVRo6dKhcLlcftLxNbW2tcnNztW/fPqWkpPTpvtG3qJVZqJc5qJU5TKuVbduqq6vTsGHDjrttr8PLsmXLuuzpaG/r1q2aMmVKZP7AgQOaM2eOrrrqKt14443HfY6jQ4dt28cMIj6fTz6fr8OytLS04z7HyUhJSTHiFwHUyjTUyxzUyhwm1ep4PS6teh1eFi1apGuuuabbbdofsjlw4IBmzZqlqVOnatWqVd0+Ljs7W5LTA5OTkxNZXllZ2ak3BgAADE69Di8ZGRnKyMjo0bb79+/XrFmzVFBQoNWrV8vt7v7kpry8PGVnZ2vjxo06//zzJUmBQECbNm3Sf/zHf/S2qQAA4DQUtVOlDxw4oJkzZyo3N1f333+/Dh48qIqKisi4llZnn3221q9fL8k5XLR48WLdd999Wr9+vT788EMtWLBACQkJuvbaa6PV1B7z+Xy65557Oh2mwsBDrcxCvcxBrcxxOtfKZffknKQTsGbNGv3rv/5rl+vaP6XL5dLq1au1YMGCyLrly5fr8ccfV3V1tS644AI9/PDDOuecc6LRTAAAYJiohRcAAIBo4LuNAACAUQgvAADAKIQXAABgFMILAAAwCuGlhx555BHl5eUpLi5OBQUFevvtt/u7SZD01ltvad68eRo2bJhcLpdeeumlDutt29ayZcs0bNgwxcfHa+bMmfroo4/6p7GD3IoVK/TlL39ZycnJyszM1BVXXKFdu3Z12IZ6DQyPPvqoJk2aFLky69SpU/XXv/41sp46DVwrVqyIXHak1elYL8JLD7zwwgtavHix7rrrLm3btk3Tp0/X3LlzVVZW1t9NG/QaGho0efJkPfTQQ12u//Wvf60HHnhADz30kLZu3ars7GxdeumlqqurO8UtxaZNm3TrrbfqnXfe0caNGxUMBjV79mw1NDREtqFeA8Pw4cP1q1/9Su+++67effddXXzxxbr88ssjb3jUaWDaunWrVq1apUmTJnVYflrWy8ZxfeUrX7EXLlzYYdnZZ59t33HHHf3UInRFkr1+/frIfCgUsrOzs+1f/epXkWXNzc12amqq/dhjj/VDC9FeZWWlLcnetGmTbdvUa6AbMmSI/eSTT1KnAaqurs7Oz8+3N27caM+YMcP+yU9+Ytv26fv/ip6X4wgEAnrvvfc0e/bsDstnz56tzZs391Or0BOlpaWqqKjoUDufz6cZM2ZQuwGgpqZGkpSeni6Jeg1UlmXp+eefV0NDg6ZOnUqdBqhbb71V3/zmN/X1r3+9w/LTtV69/m6jwebQoUOyLKvTF0NmZWV1+qoDDCyt9emqdnv37u2PJiHMtm0VFhbqa1/7WuTq2dRrYNm+fbumTp2q5uZmJSUlaf369ZowYULkDY86DRzPP/+83n//fW3durXTutP1/xXhpYdcLleHedu2Oy3DwETtBp5Fixbpgw8+0N/+9rdO66jXwDBu3DgVFxfryJEjWrdunW644QZt2rQpsp46DQz79u3TT37yE73++uuKi4s75nanW704bHQcGRkZ8ng8nXpZKisrOyVZDCzZ2dmSRO0GmB//+Md6+eWX9eabb2r48OGR5dRrYImNjdXYsWM1ZcoUrVixQpMnT9Z//dd/UacB5r333lNlZaUKCgrk9Xrl9Xq1adMmPfjgg/J6vZGanG71IrwcR2xsrAoKCrRx48YOyzdu3Khp06b1U6vQE3l5ecrOzu5Qu0AgoE2bNlG7fmDbthYtWqQXX3xRb7zxhvLy8jqsp14Dm23b8vv91GmAueSSS7R9+3YVFxdHpilTpuh73/ueiouLNXr06NOyXhw26oHCwkJdd911mjJliqZOnapVq1aprKxMCxcu7O+mDXr19fUqKSmJzJeWlqq4uFjp6ekaMWKEFi9erPvuu0/5+fnKz8/Xfffdp4SEBF177bX92OrB6dZbb9Vzzz2nP/3pT0pOTo58EkxNTVV8fHzk2hTUq//deeedmjt3rnJzc1VXV6fnn39eRUVFevXVV6nTAJOcnBwZN9YqMTFRQ4cOjSw/LevVfyc6meXhhx+2R44cacfGxtpf+tKXIqd3on+9+eabtqRO0w033GDbtnOa4D333GNnZ2fbPp/Pvuiii+zt27f3b6MHqa7qJMlevXp1ZBvqNTB8//vfj/y9O+OMM+xLLrnEfv311yPrqdPA1v5Uads+Pevlsm3b7qfcBAAA0GuMeQEAAEYhvAAAAKMQXgAAgFEILwAAwCiEFwAAYBTCCwAAMArhBQAAGIXwAgAAjEJ4AQAARiG8AAAAoxBeAACAUf5/XbjGyFwhRXsAAAAASUVORK5CYII=", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" } ], "source": [ @@ -1898,7 +2105,7 @@ }, { "cell_type": "code", - "execution_count": 327, + "execution_count": 46, "metadata": {}, "outputs": [ { @@ -1909,14 +2116,15 @@ ] }, { - "data": { - "image/png": "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m6cVK1Zo2bJlevLJJ4/re+CwEQAAJ5GxY8fq0ksv1c0336wnnnhCqampuvvuu3XKKafo0ksvlSQtWLBAc+bM0amnnqrq6mq9++674WDzi1/8QlOmTNHEiRPl8/n017/+tV3oOR7oeQEA4CTz3HPPacqUKfr2t7+tadOmybIsrV69WnFxcZIk0zR1++23a8KECZo9e7bGjRunRx99VJIUHx+vRYsW6fTTT9cFF1wgt9utl1566bi2n54XAABOAmvXrg0/Hjx4sF544YUulw2d39KZe++9V/fee29fNi1i9LwAAABHIbwAAABHIbwAAABHIbwAAABHIbwAAABHIbwAAABHIbwAAABHIbwAAABHIbwAAABHIbwAAIAOCgsLZRiGLr/8cpmm2d/NaYfwAgDASWDevHkyDEOGYcjj8WjYsGG69dZbVV1d3WHZ+++/X0899ZSeeOIJbdy4UT/84Q87LLN27VpdeumlysvLU3Jyss4880y9+OKLx+OtEF4AADhZzJ49W+Xl5dq7d6+efvppvf7667rtttvaLfPkk0/qD3/4g9asWaMf/OAHWr9+vdasWaOf/vSn7ZbbsGGDTj/9dK1cuVKffPKJvve97+mGG27Q66+/HvP3wQ8zAgDQG5YlNTd2nOdvklymZBixe+24pIi27/V6lZubK0kaOnSorr76ai1fvjz8/F/+8hfdd999evfdd3XmmWdKksaOHau//e1vuuiii5SZmam77rpLknTPPfe02/Ydd9yht99+W6tWrdLcuXN79766QXgBAKA3mhul3+S3m2VISjwer33Pfik+OapV9+zZo7feektxcXHheVdeeaWuvPLKDssOGzZMu3bt6nabNTU1mjBhQlTtiQThBQCAk8Rf//pXpaSkyDRNNTU1SZKWLl3aJ9v+y1/+ok2bNumJJ57ok+0dC+EFAIDeiEuye0DasCxLTU1NSkhIkBHrw0YRmDlzph577DE1Njbq6aef1ueff64f/ehHvW7G2rVrNW/ePD311FOaOHFir7fXHcILAAC9YRgdD91YlhRwS/EJsT3nJULJyckaM2aMJOmhhx7SzJkztWTJEv3qV7+Kepvr1q3T3LlztXTpUt1www191dRjiunVRuvXr9fcuXOVn58vwzD06quvHnP5tWvXhi/jajt89tlnsWwmAAAnpfvuu08PPvig9u/f3/3CnVi7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AAA4CuEFAAA4CuEFAAA4CuEFAAA4CuEFAAA4SkzDy/3336/zzjtPSUlJGjRoUI/WsSxLixcvVn5+vhITEzVjxgxt27Ytls0EAAAOEtPw4vf7ddVVV+nWW2/t8Tq/+93vtHTpUj388MPatGmTcnNz9c1vflN1dXUxbCkAAHCKmIaXJUuW6M4779TkyZN7tLxlWVq2bJl+9rOf6fLLL9ekSZP0/PPPq7GxUX/+859j2VQAAOAQnv5uQFslJSWqqKjQrFmzwvO8Xq+mT5+uDRs26Ic//GGHdXw+n3w+X3i6trZWkmSapkzT7NP2maapQCDQ59s9GVC76FG76FG76FG73qF+kYukVgMqvFRUVEiScnJy2s3PyclRaWlpp+sUFRVpyZIlHebv3r1bKSkpfdq+QCCgqqoqFRcXy+XiXOdIULvoUbvoUbvoUbveoX6Rq6+v7/GyEYeXxYsXdxoW2tq0aZOmTp0a6abDDMNoN21ZVod5IYsWLVJhYWF4ura2VgUFBRo9erTS0tKibkNnTNNUcXGxxowZI7fb3afbPtFRu+hRu+hRu+hRu96hfpELHTnpiYjDy/z583XNNdccc5kRI0ZEullJUm5uriS7ByYvLy88v7KyskNvTIjX65XX6+0w3+12x+QD43K5YrbtEx21ix61ix61ix616x3qF5lI6hRxeMnKylJWVlakq/XIyJEjlZubqzVr1uiss86SZF+xtG7dOv32t7+NyWsCAABniemBuLKyMm3ZskVlZWUyTVNbtmzRli1b2h3XGj9+vFatWiXJPly0YMEC/eY3v9GqVav06aefat68eUpKStJ1110Xy6YCAACHiOkJu7/4xS/0/PPPh6dDvSnvvfeeZsyYIUnauXOnampqwsvcddddOnr0qG677TZVV1frnHPO0TvvvKPU1NRYNhUAADhETMPL8uXLtXz58mMuY1lWu2nDMLR48WItXrw4dg0DAACOxfVbAADAUQgvAADAUQgvAADAUQgvAADAUQgvAADAUQgvAADAUQgvAADAUQgvAADAUQgvAADAUQgvAADAUQgvAADAUQgvAADAUQgvAADAUQgvAADAUQgvAADAUQgvAADAUQgvAADAUQgvAADAUQgvAADAUQgvAADAUQgvAADAUQgvAADAUQgvAADAUQgvAADAUQgvAADAUQgvAADAUQgvAADAUQgvAADAUQgvAADAUQgvAADAUQgvAADAUQgvAADAUQgvAADAUQgvAADAUQgvAADAUWIaXu6//36dd955SkpK0qBBg3q0zrx582QYRrvh3HPPjWUzAQCAg8Q0vPj9fl111VW69dZbI1pv9uzZKi8vDw+rV6+OUQsBAIDTeGK58SVLlkiSli9fHtF6Xq9Xubm5MWgRAABwupiGl2itXbtW2dnZGjRokKZPn677779f2dnZnS7r8/nk8/nC07W1tZIk0zRlmmaftss0TQUCgT7f7smA2kWP2kWP2kWP2vUO9YtcJLUacOFlzpw5uuqqqzR8+HCVlJTo5z//uS688EJ99NFH8nq9HZYvKioK9/C0tXv3bqWkpPRp2wKBgKqqqlRcXCyXi3OdI0Htokftokftokfteof6Ra6+vr7HyxqWZVmRbHzx4sWdhoW2Nm3apKlTp4anly9frgULFujIkSORvJQkqby8XMOHD9dLL72kyy+/vMPznfW8FBQUqKqqSmlpaRG/3rGYpqni4mKNGTNGbre7T7d9oqN20aN20aN20aN2vUP9IldbW6uMjAzV1NR0u/+OuOdl/vz5uuaaa465zIgRIyLdbJfy8vI0fPhw7dq1q9PnvV5vpz0ybrc7Jh8Yl8sVs22f6Khd9Khd9Khd9Khd71C/yERSp4jDS1ZWlrKysiJdLWqHDx/Wvn37lJeXd9xeEwAADFwxPRBXVlamLVu2qKysTKZpasuWLdqyZUu741rjx4/XqlWrJNnHuxYuXKiNGzdq7969Wrt2rebOnausrCx95zvfiWVTAQCAQ8T0hN1f/OIXev7558PTZ511liTpvffe04wZMyRJO3fuVE1NjSS7y2jr1q164YUXdOTIEeXl5WnmzJl6+eWXlZqaGsumAgAAh4hpeFm+fHm393hpe75wYmKi3n777Vg2CQAAOBzXbwEAAEchvAAAAEchvAAAAEchvAAAAEchvAAAAEchvAAAAEchvAAAAEchvAAAAEchvAAAAEchvAAAAEchvAAAAEchvAAAAEchvAAAAEchvAAAAEchvAAAAEchvAAAAEchvAAAAEchvAAAAEchvAAAAEchvAAAAEchvAAAAEchvAAAAEchvAAAAEchvAAAAEchvAAAAEchvAAAAEchvAAAAEchvAAAAEchvAAAAEchvAAAAEchvAAAAEchvAAAAEchvAAAAEchvAAAAEchvAAAAEchvAAAAEeJWXjZu3evvv/972vkyJFKTEzU6NGjdd9998nv9x9zPcuytHjxYuXn5ysxMVEzZszQtm3bYtVMAADgMDELL5999pkCgYCeeOIJbdu2Tf/5n/+pxx9/XPfcc88x1/vd736npUuX6uGHH9amTZuUm5urb37zm6qrq4tVUwEAgIN4YrXh2bNna/bs2eHpUaNGaefOnXrsscf04IMPdrqOZVlatmyZfvazn+nyyy+XJD3//PPKycnRn//8Z/3whz/ssI7P55PP5wtP19TUSJKqq6tlmmZfviWZpqna2lpVV1fL7Xb36bZPdNQuetQuetQuetSud6hf5GprayXZWaA7MQsvnampqVFGRkaXz5eUlKiiokKzZs0Kz/N6vZo+fbo2bNjQaXgpKirSkiVLOswfMWJEn7QZAAAcP3V1dUpPTz/mMsctvOzevVt//OMf9Yc//KHLZSoqKiRJOTk57ebn5OSotLS003UWLVqkwsLC8HQgEFBVVZUyMzNlGEYftLxVbW2tCgoKtG/fPqWlpfXptk901C561C561C561K53qF/kLMtSXV2d8vPzu1024vCyePHiTns62tq0aZOmTp0ant6/f79mz56tq666SjfddFO3r/Hl0GFZVpdBxOv1yuv1tps3aNCgbl+jN9LS0vgwRonaRY/aRY/aRY/a9Q71i0x3PS4hEYeX+fPn65prrjnmMm0P2ezfv18zZ87UtGnT9OSTTx5zvdzcXEl2D0xeXl54fmVlZYfeGAAAcHKKOLxkZWUpKyurR8t+8cUXmjlzpqZMmaLnnntOLtexL24aOXKkcnNztWbNGp111lmSJL/fr3Xr1um3v/1tpE0FAAAnoJhdKr1//37NmDFDBQUFevDBB3Xw4EFVVFSEz2sJGT9+vFatWiXJPly0YMEC/eY3v9GqVav06aefat68eUpKStJ1110Xq6b2mNfr1X333dfhMBW6R+2iR+2iR+2iR+16h/rFlmH15JqkKCxfvlz/8R//0elzbV/SMAw999xzmjdvXvi5JUuW6IknnlB1dbXOOeccPfLII5o0aVIsmgkAABwmZuEFAAAgFvhtIwAA4CiEFwAA4CiEFwAA4CiEFwAA4CiElx569NFHNXLkSCUkJGjKlCn629/+1t9NGpDWr1+vuXPnKj8/X4Zh6NVXX233vGVZWrx4sfLz85WYmKgZM2Zo27Zt/dPYAaSoqEhf/epXlZqaquzsbF122WXauXNnu2WoXdcee+wxnX766eG7mU6bNk1vvvlm+Hlq1zNFRUXhW1aEULuuLV68WIZhtBtCN1uVqF0sEV564OWXX9aCBQv0s5/9TJs3b9b555+vOXPmqKysrL+bNuA0NDTojDPO0MMPP9zp87/73e+0dOlSPfzww9q0aZNyc3P1zW9+U3V1dce5pQPLunXrdPvtt+uDDz7QmjVr1NLSolmzZqmhoSG8DLXr2tChQ/XAAw/oww8/1IcffqgLL7xQl156aXhHQe26t2nTJj355JM6/fTT282ndsc2ceJElZeXh4etW7eGn6N2MWShW2effbZ1yy23tJs3fvx46+677+6nFjmDJGvVqlXh6UAgYOXm5loPPPBAeF5TU5OVnp5uPf744/3QwoGrsrLSkmStW7fOsixqF43BgwdbTz/9NLXrgbq6Omvs2LHWmjVrrOnTp1s//vGPLcvic9ed++67zzrjjDM6fY7axRY9L93w+/366KOPNGvWrHbzZ82apQ0bNvRTq5yppKREFRUV7Wrp9Xo1ffp0avklNTU1kqSMjAxJ1C4SpmnqpZdeUkNDg6ZNm0bteuD222/Xt771LX3jG99oN5/adW/Xrl3Kz8/XyJEjdc0112jPnj2SqF2sRfzbRiebQ4cOyTTNDj8MmZOT0+GnDnBsoXp1VsvS0tL+aNKAZFmWCgsL9fWvfz18Z2lq172tW7dq2rRpampqUkpKilatWqXTTjstvKOgdp176aWX9PHHH2vTpk0dnuNzd2znnHOOXnjhBZ166qk6cOCAfv3rX+u8887Ttm3bqF2MEV56yDCMdtOWZXWYh56hlsc2f/58ffLJJ3r//fc7PEftujZu3Dht2bJFR44c0cqVK3XjjTdq3bp14eepXUf79u3Tj3/8Y73zzjtKSEjocjlq17k5c+aEH0+ePFnTpk3T6NGj9fzzz+vcc8+VRO1ihcNG3cjKypLb7e7Qy1JZWdkhUePYQmfhU8uu/ehHP9Jrr72m9957T0OHDg3Pp3bdi4+P15gxYzR16lQVFRXpjDPO0H/9139Ru2P46KOPVFlZqSlTpsjj8cjj8WjdunV66KGH5PF4wvWhdj2TnJysyZMna9euXXzuYozw0o34+HhNmTJFa9asaTd/zZo1Ou+88/qpVc40cuRI5ebmtqul3+/XunXrTvpaWpal+fPn65VXXtG7776rkSNHtnue2kXOsiz5fD5qdwwXXXSRtm7dqi1btoSHqVOn6rvf/a62bNmiUaNGUbsI+Hw+7dixQ3l5eXzuYq3fThV2kJdeesmKi4uznnnmGWv79u3WggULrOTkZGvv3r393bQBp66uztq8ebO1efNmS5K1dOlSa/PmzVZpaallWZb1wAMPWOnp6dYrr7xibd261br22mutvLw8q7a2tp9b3r9uvfVWKz093Vq7dq1VXl4eHhobG8PLULuuLVq0yFq/fr1VUlJiffLJJ9Y999xjuVwu65133rEsi9pFou3VRpZF7Y7lJz/5ibV27Vprz5491gcffGB9+9vftlJTU8P7BmoXO4SXHnrkkUes4cOHW/Hx8dZXvvKV8CWsaO+9996zJHUYbrzxRsuy7MsH77vvPis3N9fyer3WBRdcYG3durV/Gz0AdFYzSdZzzz0XXobade173/te+N/nkCFDrIsuuigcXCyL2kXiy+GF2nXt6quvtvLy8qy4uDgrPz/fuvzyy61t27aFn6d2sWNYlmX1T58PAABA5DjnBQAAOArhBQAAOArhBQAAOArhBQAAOArhBQAAOArhBQAAOArhBQAAOArhBQAAOArhBQAAOArhBQAAOArhBQAAOMr/Dy6WaXmx0djlAAAAAElFTkSuQmCC", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" + "ename": "NameError", + "evalue": "name 'plt' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[46], line 57\u001b[0m\n\u001b[1;32m 55\u001b[0m \u001b[38;5;66;03m# Plot the loss curve\u001b[39;00m\n\u001b[1;32m 56\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m solver \u001b[38;5;241m!=\u001b[39m \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mlbfgs\u001b[39m\u001b[38;5;124m'\u001b[39m:\n\u001b[0;32m---> 57\u001b[0m \u001b[43mplt\u001b[49m\u001b[38;5;241m.\u001b[39mplot(dc50_regr\u001b[38;5;241m.\u001b[39mloss_curve_, label\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mloss\u001b[39m\u001b[38;5;124m'\u001b[39m)\n\u001b[1;32m 58\u001b[0m plt\u001b[38;5;241m.\u001b[39mplot(dc50_regr\u001b[38;5;241m.\u001b[39mvalidation_scores_, label\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mR^2\u001b[39m\u001b[38;5;124m'\u001b[39m)\n\u001b[1;32m 59\u001b[0m plt\u001b[38;5;241m.\u001b[39mgrid(axis\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mboth\u001b[39m\u001b[38;5;124m'\u001b[39m, alpha\u001b[38;5;241m=\u001b[39m\u001b[38;5;241m0.5\u001b[39m)\n", + "\u001b[0;31mNameError\u001b[0m: name 'plt' is not defined" + ] } ], "source": [ @@ -1986,7 +2194,7 @@ }, { "cell_type": "code", - "execution_count": 337, + "execution_count": null, "metadata": {}, "outputs": [ { @@ -5121,7 +5329,7 @@ }, { "cell_type": "code", - "execution_count": 357, + "execution_count": 48, "metadata": {}, "outputs": [], "source": [ @@ -5139,7 +5347,7 @@ }, { "cell_type": "code", - "execution_count": 360, + "execution_count": 49, "metadata": {}, "outputs": [ { @@ -5184,7 +5392,7 @@ }, { "cell_type": "code", - "execution_count": 361, + "execution_count": 50, "metadata": {}, "outputs": [ { @@ -5231,7 +5439,7 @@ }, { "cell_type": "code", - "execution_count": 362, + "execution_count": 57, "metadata": {}, "outputs": [ { @@ -5239,13 +5447,13 @@ "output_type": "stream", "text": [ "Number of unique groups: 71\n", - "Number of entries in the test set: 170 (19.8%)\n", + "Number of entries in the test set: 171 (20.0%)\n", "Active/inactive PROTACs in the test set:\n", - "False 0.56\n", - "True 0.44\n", + "False 0.53\n", + "True 0.47\n", "Name: Active (Dmax 0.6, pDC50 6.0), dtype: float64\n", "Number of SMILES leaking in the train_val_df dataset: 0\n", - "Number of Uniprot leaking in the train_val_df dataset: 32\n" + "Number of Uniprot leaking in the train_val_df dataset: 25\n" ] } ], @@ -5266,13 +5474,17 @@ "# plt.grid(axis='y', alpha=0.5)\n", "# plt.show()\n", "\n", + "# Get the groups ordered by the average tanimoto distance (highest to lowest)\n", + "# NOTE: This will put the \"less similar\" PROTACs in the test set\n", + "tanimoto_groups = active_df.groupby('Tanimoto Group')['Avg Tanimoto'].mean().sort_values(ascending=False).index\n", + "\n", "test_df = []\n", "# For each group, get the number of active and inactive entries. Then, add those\n", "# entries to the test_df if: 1) the test_df lenght + the group entries is less\n", "# 20% of the active_df lenght, and 2) the percentage of True and False entries\n", "# in the active_col in test_df is roughly 50%.\n", "# Start the loop from the groups containing the smallest number of entries.\n", - "for group in reversed(active_df['Tanimoto Group'].value_counts().index):\n", + "for group in tanimoto_groups:\n", " group_df = active_df[active_df['Tanimoto Group'] == group]\n", " if test_df == []:\n", " test_df.append(group_df)\n", @@ -5292,8 +5504,8 @@ " if num_entries_test + num_entries < 0.1 * len(active_df):\n", " test_df.append(group_df)\n", " continue\n", - " if (num_active_group + num_active_test) / (num_entries_test + num_entries) < 0.6:\n", - " if (num_inactive_group + num_inactive_test) / (num_entries_test + num_entries) < 0.6:\n", + " if (num_active_group + num_active_test) / (num_entries_test + num_entries) < 0.55:\n", + " if (num_inactive_group + num_inactive_test) / (num_entries_test + num_entries) < 0.55:\n", " test_df.append(group_df)\n", "test_df = pd.concat(test_df)\n", "# Save to global dictionary of test indeces\n", @@ -5311,6 +5523,22 @@ "print(f'Number of Uniprot leaking in the train_val_df dataset: {len(uniprot_leak)}')" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "```\n", + "Number of unique groups: 71\n", + "Number of entries in the test set: 170 (19.8%)\n", + "Active/inactive PROTACs in the test set:\n", + "False 0.56\n", + "True 0.44\n", + "Name: Active (Dmax 0.6, pDC50 6.0), dtype: float64\n", + "Number of SMILES leaking in the train_val_df dataset: 0\n", + "Number of Uniprot leaking in the train_val_df dataset: 32\n", + "```" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -12932,7 +13160,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3", + "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, @@ -12946,7 +13174,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.0" + "version": "3.10.8" } }, "nbformat": 4,