{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# `ContaminationDetector` in action\n", "\n", "In this example, we apply `ContaminationDetector` from `coSMicQC` on an example dataset from the NF1 project.\n", "\n", "The NF1 project example includes wells from a cell line that was contaminated with mycoplasma.\n", "In the wet lab, these cells were detected as negative for mycoplasma.\n", "We do not want to process contaminated cells, so we can use this methodology to confirm the contamination and the extent of it on the plate.\n", "\n", "The result of this method is either a pass or fail.\n", "If the data is clean, then the method stops at step 1 and says the data is ready for further downstream analysis.\n", "If the data has contamination, this method will continue processing after step 1 to determine if the problem is for the whole plate or part of the plate.\n" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import pandas as pd\n", "\n", "from cosmicqc import ContaminationDetector\n", "\n", "# set a path for the NF1 parquet-based dataset\n", "data_path = (\n", " \"../../../tests/data/cytotable/NF1_cellpainting_data/Plate_3_filtered.parquet\"\n", ")" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(1355, 2321)\n" ] }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
Metadata_ImageNumberImage_Metadata_PlateMetadata_number_of_singlecellsImage_Metadata_SiteImage_Metadata_WellMetadata_Cells_Number_Object_NumberMetadata_Cytoplasm_Parent_CellsMetadata_Cytoplasm_Parent_NucleiMetadata_Nuclei_Number_Object_NumberImage_FileName_CY5...Nuclei_Texture_Variance_DAPI_3_02_256Nuclei_Texture_Variance_DAPI_3_03_256Nuclei_Texture_Variance_GFP_3_00_256Nuclei_Texture_Variance_GFP_3_01_256Nuclei_Texture_Variance_GFP_3_02_256Nuclei_Texture_Variance_GFP_3_03_256Nuclei_Texture_Variance_RFP_3_00_256Nuclei_Texture_Variance_RFP_3_01_256Nuclei_Texture_Variance_RFP_3_02_256Nuclei_Texture_Variance_RFP_3_03_256
030Plate_327915B111122B11_01_3_15_CY5_001_illumcorrect.tiff...619.327600594.798669271.137249268.157417311.088206282.370923198.402061202.133683203.094321193.875072
131Plate_327916B111122B11_01_3_16_CY5_001_illumcorrect.tiff...323.170295321.31071134.84114535.13911438.07520638.080602131.691809126.174866136.433036132.735107
234Plate_327919B111122B11_01_3_19_CY5_001_illumcorrect.tiff...321.457911314.851226286.810209261.637391257.878700259.463388157.252242156.042241154.576787154.894240
335Plate_32791B111122B11_01_3_1_CY5_001_illumcorrect.tiff...1487.3540341468.971582516.742751489.945367519.912829510.173091369.462002366.631748383.771987364.529179
444Plate_32796B111122B11_01_3_6_CY5_001_illumcorrect.tiff...508.054695501.77049751.69532754.24862357.98486952.494053262.420251255.894670259.081931266.519397
\n", "

5 rows × 2321 columns

\n", "
" ], "text/plain": [ " Metadata_ImageNumber Image_Metadata_Plate Metadata_number_of_singlecells \\\n", "0 30 Plate_3 279 \n", "1 31 Plate_3 279 \n", "2 34 Plate_3 279 \n", "3 35 Plate_3 279 \n", "4 44 Plate_3 279 \n", "\n", " Image_Metadata_Site Image_Metadata_Well \\\n", "0 15 B11 \n", "1 16 B11 \n", "2 19 B11 \n", "3 1 B11 \n", "4 6 B11 \n", "\n", " Metadata_Cells_Number_Object_Number Metadata_Cytoplasm_Parent_Cells \\\n", "0 1 1 \n", "1 1 1 \n", "2 1 1 \n", "3 1 1 \n", "4 1 1 \n", "\n", " Metadata_Cytoplasm_Parent_Nuclei Metadata_Nuclei_Number_Object_Number \\\n", "0 2 2 \n", "1 2 2 \n", "2 2 2 \n", "3 2 2 \n", "4 2 2 \n", "\n", " Image_FileName_CY5 ... \\\n", "0 B11_01_3_15_CY5_001_illumcorrect.tiff ... \n", "1 B11_01_3_16_CY5_001_illumcorrect.tiff ... \n", "2 B11_01_3_19_CY5_001_illumcorrect.tiff ... \n", "3 B11_01_3_1_CY5_001_illumcorrect.tiff ... \n", "4 B11_01_3_6_CY5_001_illumcorrect.tiff ... \n", "\n", " Nuclei_Texture_Variance_DAPI_3_02_256 Nuclei_Texture_Variance_DAPI_3_03_256 \\\n", "0 619.327600 594.798669 \n", "1 323.170295 321.310711 \n", "2 321.457911 314.851226 \n", "3 1487.354034 1468.971582 \n", "4 508.054695 501.770497 \n", "\n", " Nuclei_Texture_Variance_GFP_3_00_256 Nuclei_Texture_Variance_GFP_3_01_256 \\\n", "0 271.137249 268.157417 \n", "1 34.841145 35.139114 \n", "2 286.810209 261.637391 \n", "3 516.742751 489.945367 \n", "4 51.695327 54.248623 \n", "\n", " Nuclei_Texture_Variance_GFP_3_02_256 Nuclei_Texture_Variance_GFP_3_03_256 \\\n", "0 311.088206 282.370923 \n", "1 38.075206 38.080602 \n", "2 257.878700 259.463388 \n", "3 519.912829 510.173091 \n", "4 57.984869 52.494053 \n", "\n", " Nuclei_Texture_Variance_RFP_3_00_256 Nuclei_Texture_Variance_RFP_3_01_256 \\\n", "0 198.402061 202.133683 \n", "1 131.691809 126.174866 \n", "2 157.252242 156.042241 \n", "3 369.462002 366.631748 \n", "4 262.420251 255.894670 \n", "\n", " Nuclei_Texture_Variance_RFP_3_02_256 Nuclei_Texture_Variance_RFP_3_03_256 \n", "0 203.094321 193.875072 \n", "1 136.433036 132.735107 \n", "2 154.576787 154.894240 \n", "3 383.771987 364.529179 \n", "4 259.081931 266.519397 \n", "\n", "[5 rows x 2321 columns]" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Load in the dataset\n", "filtered_nf1_df = pd.read_parquet(data_path)\n", "\n", "# Look over the data to check it is correct\n", "print(filtered_nf1_df.shape)\n", "filtered_nf1_df.head()" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Running step 1...\n", "Summary:\n", "\n", "Check Result\n", "----------------------- --------\n", "Texture skewed? ✅\n", "Nucleus shape variable? ❌\n", "Interpretation:\n", "Contamination detected! 🚨\n", "Anomalous texture around nuclei detected but nuclei segmentation not clearly impacted.\n", "Proceeding to step 2...\n", "Running step 2...\n", "Summary:\n", "\n", "Check Result\n", "------------------------------------------------------- --------\n", "Texture skewed? ✅\n", "Nucleus shape variable? ❌\n", "Whole plate contaminated due to abnormal texture? ❌\n", "Whole plate contaminated due to abnormal nucleus shape? ❌\n", "Interpretation:\n", "Partial plate contamination in texture only. Proceed to step 3.\n", "Running step 3...\n", "Finding outlier cells with anomalous texture around the nucleus...\n", "Number of outliers: 198 (14.61%)\n", "Outliers Range:\n", "Cytoplasm_Texture_InfoMeas1_DAPI_3_02_256 Min: -0.3808007336913458\n", "Cytoplasm_Texture_InfoMeas1_DAPI_3_02_256 Max: -0.23152918999076016\n", "Number of outliers: 120 (8.86%)\n", "Outliers Range:\n", "Cytoplasm_Granularity_2_DAPI Min: 1.8500394938002351\n", "Cytoplasm_Granularity_2_DAPI Max: 27.639655282904474\n", "Total number of outliers detected: 242\n" ] }, { "data": { "image/png": "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6PwGAAAAAKAF0vkNAAAAAFAhNSmlJqWyx0TnNwAAAAAALZDObwAAAACACqkp2qSmKG+Pck1h5nei+A0AAAAAUDErbnhZ3jEl5Y7XXBl7AgAAAABAi6PzGwAAAACgQmrTJjVl7lGujbEnic5vAAAAAABaIMVvAAAAAIAKee+Gl+U+Vsb48eOz/fbbp2vXrunVq1eGDx+eKVOm1Ltm1113TalUqnd85zvfqXfN9OnTs/fee6dz587p1atXTj755CxfvvxTf40aytgTAAAAAIBWbMKECRk5cmS23377LF++PKeffnr22GOPvPDCC+nSpUvddUcccUTOOeecusedO3eu+3NNTU323nvv9OnTJ3/84x/z17/+NYccckjat2+fCy64YJW+nvcofgMAAAAAVEht2qS2wjO/77777nqPr7vuuvTq1StPP/10dtlll7r1zp07p0+fPh8a4/e//31eeOGF3Hfffendu3e22mqrnHvuuTn11FNz9tlnp0OHDiv/Qj4lY08AAAAAAFqgefPm1TuWLFnyiZ43d+7cJEmPHj3qrd94441ZY401stlmm2Xs2LFZuHBh3bnHHnssm2++eXr37l23NnTo0MybNy/PP/98GV7NytP5DQAAAABQITVFKTVFqewxk6R///711s8666ycffbZ//K5tbW1OeGEE7LTTjtls802q1v/+te/nnXWWSf9+vXLs88+m1NPPTVTpkzJbbfdliSZOXNmvcJ3krrHM2fO/LQvqUEUvwEAAAAAKqQmbVJT5gEdNf8YezJjxoxUV1fXrVdVVX3sc0eOHJnnnnsujz76aL31I488su7Pm2++efr27Zvdd989r776atZbb70yZV5exp4AAAAAALRA1dXV9Y6PK36PGjUqd911Vx588MGstdZa//LaHXbYIUnyyiuvJEn69OmTWbNm1bvmvccfNSe8sSl+AwAAAABUSG3RplGOlVEURUaNGpVf//rXeeCBBzJgwICPfc7kyZOTJH379k2SDBw4MH/+85/z9ttv111z7733prq6OptssslK5VMuxp4AAAAAALRiI0eOzE033ZTf/OY36dq1a92M7m7duqVTp0559dVXc9NNN2WvvfbK6quvnmeffTajR4/OLrvski222CJJsscee2STTTbJN7/5zVx88cWZOXNmzjjjjIwcOfITjVtpDIrfAAAAAAAV0pgzvz+pq6++Okmy66671lu/9tprc9hhh6VDhw657777cumll2bBggXp379/RowYkTPOOKPu2rZt2+auu+7K0UcfnYEDB6ZLly459NBDc84553zq19NQit8AAAAAAK1YUfzrYnn//v0zYcKEj42zzjrr5He/+1250vrUFL8BAAAAACqkNklNUSp7TNzwEgAAAACAFkjnNwAAAABAhdSmTWrL3KNc7njNleI3AAAAAECF1BRtUlOU+YaXZY7XXPkqAAAAAADQ4uj8BgAAAACokNqUUpty3/CyvPGaK53fAAAAAAC0ODq/AQAAAAAqxMzvxuOrAAAAAABAi6PzGwAAAACgQmrSJjVl7lEud7zmylcBAAAAAIAWR+c3AAAAAECF1Bal1BalssdE8RsAAAAAoGJqG2HsSa2BH0mMPQEAAAAAoAXS+Q0AAAAAUCG1RZvUFmXu/C5zvObKVwEAAAAAgBZH5zcAAAAAQIXUpJSalPcGleWO11zp/AYAAAAAoMXR+Q0AAAAAUCFmfjceXwUAAAAAAFocnd8AAAAAABVSk/LP6K4pa7TmS/EbAAAAAKBCjD1pPL4KAAAAAAC0ODq/AQAAAAAqpKZok5oyd2qXO15z5asAAAAAAECL06SL3zU1NRk3blwGDBiQTp06Zb311su5556boijqrimKImeeeWb69u2bTp06ZciQIZk6dWoFswYAAAAA+GSKlFJb5qMo8w00m6smXfy+6KKLcvXVV+fHP/5xXnzxxVx00UW5+OKLc8UVV9Rdc/HFF+fyyy/PNddck4kTJ6ZLly4ZOnRoFi9eXMHMAQAAAACopCY98/uPf/xjvvzlL2fvvfdOkqy77rr5xS9+kSeeeCLJiq7vSy+9NGeccUa+/OUvJ0luuOGG9O7dO7fffnsOOuigiuUOAAAAAPBxzPxuPE36q/CFL3wh999/f15++eUkyTPPPJNHH300e+65Z5Jk2rRpmTlzZoYMGVL3nG7dumWHHXbIY4899pFxlyxZknnz5tU7AAAAAABoOZp05/dpp52WefPmZaONNkrbtm1TU1OT888/PwcffHCSZObMmUmS3r1713te79696859mPHjx+d73/te4yUOAAAAAPAJ1Bal1BblndFd7njNVZPu/L7lllty44035qabbsqf/vSnXH/99fn+97+f66+//lPFHTt2bObOnVt3zJgxo0wZAwAAAADQFDTpzu+TTz45p512Wt3s7s033zyvv/56xo8fn0MPPTR9+vRJksyaNSt9+/ate96sWbOy1VZbfWTcqqqqVFVVNWruAAAAAAAfpyZtUlPmHuVyx2uumvRXYeHChWnTpn6Kbdu2TW1tbZJkwIAB6dOnT+6///668/PmzcvEiRMzcODAVZorAAAAAMDKem/sSbkPmnjn97777pvzzz8/a6+9djbddNNMmjQpP/zhD/Ptb387SVIqlXLCCSfkvPPOywYbbJABAwZk3Lhx6devX4YPH17Z5AEAAAAAqJgmXfy+4oorMm7cuBxzzDF5++23069fvxx11FE588wz66455ZRTsmDBghx55JGZM2dOdt5559x9993p2LFjBTMHAAAAAPh4tWmT2jIP6Ch3vOaqVBRFUekkKm3evHnp1q1b5s6dm+rq6kqnAwAAAADNivraynvvazbq0a+karX2ZY29ZP6y/HjnX7f6/WjSnd8AAAAAAC1ZTVFKTZlndJc7XnOl/x0AAAAAgBZH5zcAAAAAQIXUFqXUlrlTu9zxmiud3wAAAAAAtDg6vwEAAAAAKqQo2qS2KG+PclHmeM2V4jcAAAAAQIXUpJSalPmGl2WO11z5CAAAAAAAgBZH5zcAAAAAQIXUFuW/QWVtUdZwzZbObwAAAAAAWhyd3wAAAAAAFVLbCDe8LHe85spXAQAAAACAFkfnNwAAAABAhdSmlNqUeeZ3meM1Vzq/AQAAAABocXR+AwAAAABUSE1RSk1R3k7tcsdrrhS/AQAAAAAqxA0vG4+vAgAAAAAALY7ObwAAAACACqlNKbVlHlPihpcr6PwGAAAAAKDF0fkNAAAAAFAhRUpl79QudH4n0fkNAAAAAEALpPMbAAAAAKBCaotGmPld5njNlc5vAAAAAABaHJ3fAAANsNd+Z1c6hRbhd3ecXekUAACgomqLNqktytujXO54zZXiNwAAAABAhRh70nh8BAAAAAAAQIuj8xsAAAAAoEJqU0ptytz5XeZ4zZXObwAAAAAAWhyd3wAAAAAAFWLmd+PR+Q0AAAAAQIuj8xsAAAAAoEJ0fjcend8AAAAAALQ4Or8BAAAAACpE53fjUfwGAAAAAKgQxe/GY+wJAAAAAAAtjs5vAAAAAIAKKZLUpryd2kVZozVfOr8BAAAAAGhxdH4DAAAAAFSImd+NR+c3AAAAAAAtjs5vAAAAAIAK0fndeHR+AwAAAADQ4uj8BgAAAACoEJ3fjUfxGwAAAACgQhS/G4+xJwAAAAAAtDg6vwEAAAAAKqQoSinK3Kld7njNlc5vAAAAAABaHJ3fAAAAAAAVUptSalPmmd9ljtdc6fwGAAAAAKDFUfwGAAAAAKiQ2qLUKMfKGD9+fLbffvt07do1vXr1yvDhwzNlypR61yxevDgjR47M6quvntVWWy0jRozIrFmz6l0zffr07L333uncuXN69eqVk08+OcuXL//UX6OGUvwGAAAAAGjFJkyYkJEjR+bxxx/Pvffem2XLlmWPPfbIggUL6q4ZPXp07rzzzvzyl7/MhAkT8tZbb2X//fevO19TU5O99947S5cuzR//+Mdcf/31ue6663LmmWdW4iUlMfMbAAAAAKBiiqKUYiU7tT9JzJVx991313t83XXXpVevXnn66aezyy67ZO7cufnZz36Wm266KbvttluS5Nprr83GG2+cxx9/PDvuuGN+//vf54UXXsh9992X3r17Z6uttsq5556bU089NWeffXY6dOhQttf3Sen8BgAAAACokMYcezJv3rx6x5IlSz5RTnPnzk2S9OjRI0ny9NNPZ9myZRkyZEjdNRtttFHWXnvtPPbYY0mSxx57LJtvvnl69+5dd83QoUMzb968PP/882X5Wq0sxW8AAAAAgBaof//+6datW90xfvz4j31ObW1tTjjhhOy0007ZbLPNkiQzZ85Mhw4d0r1793rX9u7dOzNnzqy75v2F7/fOv3euEow9AQAAAACokMYcezJjxoxUV1fXrVdVVX3sc0eOHJnnnnsujz76aFlzqgSd3wAAAAAALVB1dXW94+OK36NGjcpdd92VBx98MGuttVbdep8+fbJ06dLMmTOn3vWzZs1Knz596q6ZNWvWB86/d64SFL8BAAAAACqkaIR53yvbSV4URUaNGpVf//rXeeCBBzJgwIB657fddtu0b98+999/f93alClTMn369AwcODBJMnDgwPz5z3/O22+/XXfNvffem+rq6myyySaf4ivUcMaeAAAAAAC0YiNHjsxNN92U3/zmN+natWvdjO5u3bqlU6dO6datWw4//PCMGTMmPXr0SHV1dY499tgMHDgwO+64Y5Jkjz32yCabbJJvfvObufjiizNz5sycccYZGTly5Ccat9IYFL8BAAAAACqkSFIU5Y+5Mq6++uokya677lpv/dprr81hhx2WJPnRj36UNm3aZMSIEVmyZEmGDh2aq666qu7atm3b5q677srRRx+dgQMHpkuXLjn00ENzzjnnfIpX8ukofgMAAAAAtGLFJ6i+d+zYMVdeeWWuvPLKj7xmnXXWye9+97typvapKH4DAAAAAFRIbUopZeVmdH+SmCh+AwAAAABUTNGAG1R+kpgkbSqdAAAAAAAAlJvObwAAAACACqktSimVuVO7Vud3Ep3fAAAAAAC0QDq/AQAAAAAqpChWHOWOic5vAAAAAABaIJ3fAAAAAAAVUhSlFGWe0V3ueM2Vzm8AAAAAAFocnd8AAAAAABWi87vx6PwGAAAAAKDF0fkNAAAAAFAhtUUppTJ3atfq/E6i+A0AAAAAUDFFseIod0yMPQEAAAAAoAXS+Q0AAAAAUCErOr/LfcPLsoZrtnR+AwAAAADQ4uj8BgAAAACokKIoNULntxteJjq/AQAAAABogXR+02LsceA5lU6hxfj9f59Z6RQAAAAAWoXiH0e5Y6LzGwAAAACAFkjnNwAAAABAhZj53Xh0fgMAAAAAVErRSEcz8/DDD2f58uUfWF++fHkefvjhBsVU/AYAAAAAoKIGDx6c2bNnf2B97ty5GTx4cINiGnsCAAAAAFApjTD2JM1w7ElRFCmVPpj33/72t3Tp0qVBMZt88fvNN9/Mqaeemv/5n//JwoULs/766+faa6/Ndtttl2TFF+Wss87KT3/608yZMyc77bRTrr766mywwQYVzhwAAAAAgH9l//33T5KUSqUcdthhqaqqqjtXU1OTZ599Nl/4whcaFLtJF7/ffffd7LTTThk8eHD+53/+Jz179szUqVPzmc98pu6aiy++OJdffnmuv/76DBgwIOPGjcvQoUPzwgsvpGPHjhXMHgAAAADgXyuKFUe5YzYX3bp1S7Kiyblr167p1KlT3bkOHTpkxx13zBFHHNGg2E26+H3RRRelf//+ufbaa+vWBgwYUPfnoihy6aWX5owzzsiXv/zlJMkNN9yQ3r175/bbb89BBx30oXGXLFmSJUuW1D2eN29eI70CAAAAAAA+ynu133XXXTcnnXRSg0ecfJgmfcPLO+64I9ttt12++tWvplevXtl6663z05/+tO78tGnTMnPmzAwZMqRurVu3btlhhx3y2GOPfWTc8ePHp1u3bnVH//79G/V1AAAAAAB8mOIfM7/LfTQ3Z511VlkL30kTL37/5S9/qZvffc899+Too4/Occcdl+uvvz5JMnPmzCRJ79696z2vd+/edec+zNixYzN37ty6Y8aMGY33IgAAAAAA+JdmzZqVb37zm+nXr1/atWuXtm3b1jsaokmPPamtrc12222XCy64IEmy9dZb57nnnss111yTQw89tMFxq6qq6g1OBwAAAACoiKK04ih3zGbmsMMOy/Tp0zNu3Lj07ds3pdKnfw1Nuvjdt2/fbLLJJvXWNt544/zqV79KkvTp0yfJik8F+vbtW3fNrFmzstVWW62yPAEAAAAAGqK13/DyPY8++mgeeeSRstZ1m/TYk5122ilTpkypt/byyy9nnXXWSbLi5pd9+vTJ/fffX3d+3rx5mThxYgYOHLhKcwUAAAAAoGH69++fosxV+yZd/B49enQef/zxXHDBBXnllVdy00035d///d8zcuTIJEmpVMoJJ5yQ8847L3fccUf+/Oc/55BDDkm/fv0yfPjwyiYPAAAAAPBxikY6mplLL700p512Wl577bWyxWzSY0+23377/PrXv87YsWNzzjnnZMCAAbn00ktz8MEH111zyimnZMGCBTnyyCMzZ86c7Lzzzrn77rvTsWPHCmYOAAAAAMAndeCBB2bhwoVZb7310rlz57Rv377e+dmzZ690zCZd/E6SffbZJ/vss89Hni+VSjnnnHNyzjnnrMKsAAAAAAA+vaIopSjzDSrLHW9VuPTSS8ses8kXvwEAAAAAaNkOPfTQssdU/AYAAAAAqKRmOKO73KZPn/4vz6+99torHVPxGwAAAACAilp33XVTKn30uJaampqVjqn4DQAAAE3YXvudXekUWozf3XF2pVMA+AAzv1eYNGlSvcfLli3LpEmT8sMf/jDnn39+g2IqfgMAAAAAVEqR8o89aYZjVLbccssPrG233Xbp169fLrnkkuy///4rHbNNORIDAAAAAIBy23DDDfPkk0826Lk6vwEAAAAAKqb0j6PcMZuXefPm1XtcFEX++te/5uyzz84GG2zQoJgNKn7X1NTkuuuuy/3335+33347tbW19c4/8MADDUoGAAAAAIDWp3v37h+44WVRFOnfv39uvvnmBsVsUPH7+OOPz3XXXZe99947m2222b+8CycAAAAAAB/BzO8kyYMPPljvcZs2bdKzZ8+sv/76adeuYQNMGvSsm2++Obfcckv22muvBv2lAAAAAADwnkGDBpU9ZoOK3x06dMj6669f7lwAAAAAAFoXnd91Xn311Vx66aV58cUXkySbbLJJjj/++Ky33noNitemIU868cQTc9lll6UomulXEQAAAACAJuOee+7JJptskieeeCJbbLFFtthii0ycODGbbrpp7r333gbFbFDn96OPPpoHH3ww//M//5NNN9007du3r3f+tttua1AyAAAAAACtSlFacZQ7ZjNz2mmnZfTo0bnwwgs/sH7qqafmS1/60krHbFDxu3v37vnKV77SkKcCAAAAAPAPRbHiKHfM5ubFF1/MLbfc8oH1b3/727n00ksbFLNBxe9rr722QX8ZAAAAAAD8s549e2by5MnZYIMN6q1Pnjw5vXr1alDMBhW/3/POO+9kypQpSZINN9wwPXv2/DThAAAAAABaFze8TJIcccQROfLII/OXv/wlX/jCF5Ikf/jDH3LRRRdlzJgxDYrZoOL3ggULcuyxx+aGG25IbW1tkqRt27Y55JBDcsUVV6Rz584NSgYAAAAAgNZn3Lhx6dq1a37wgx9k7NixSZJ+/frl7LPPznHHHdegmG0a8qQxY8ZkwoQJufPOOzNnzpzMmTMnv/nNbzJhwoSceOKJDUoEAAAAAKDVee+Gl+U+mplSqZTRo0fnjTfeyNy5czN37ty88cYbOf7441MqNez1NKj4/atf/So/+9nPsueee6a6ujrV1dXZa6+98tOf/jS33nprgxIBAAAAAKB1WbRoUe644478/e9/r1vr2rVrunbtmnnz5uWOO+7IkiVLGhS7QcXvhQsXpnfv3h9Y79WrVxYuXNigRAAAAAAAWptS0ThHc/Hv//7vueyyy9K1a9cPnKuurs7ll1+e//iP/2hQ7AYVvwcOHJizzjorixcvrltbtGhRvve972XgwIENSgQAAAAAgNblxhtvzAknnPCR50844YRcf/31DYrdoBteXnbZZRk6dGjWWmutbLnllkmSZ555Jh07dsw999zToEQAAAAAAFqd4h9HuWM2E1OnTq2rMX+YLbbYIlOnTm1Q7AYVvzfbbLNMnTo1N954Y1566aUkyde+9rUcfPDB6dSpU4MSAQAAAABodRrjBpXN6IaXy5cvzzvvvJO11177Q8+/8847Wb58eYNiN6j4nSSdO3fOEUcc0dCnAwAAAADQym266aa57777su22237o+d///vfZdNNNGxT7Exe/77jjjuy5555p37597rjjjn957X777degZAAAAAAAWpVWPvbk29/+dsaMGZNNN900++yzT71zd955Z84///z88Ic/bFDsT1z8Hj58eGbOnJlevXpl+PDhH3ldqVRKTU1Ng5IBAAAAAKD1OPLII/Pwww9nv/32y0YbbZQNN9wwSfLSSy/l5ZdfzgEHHJAjjzyyQbE/cfG7trb2Q/8MAAAAAEADtfLO7yT5r//6r+y333656aab8vLLL6coimy44Yb53ve+lwMOOKDBcRs08/uGG27IgQcemKqqqnrrS5cuzc0335xDDjmkwQkBAAAAANC6HHDAAZ+q0P1h2jTkSd/61rcyd+7cD6z//e9/z7e+9a1PnRQAAAAAQKtQNNJBw4rfRVGkVCp9YP2NN95It27dPnVSAAAAAADwaazU2JOtt946pVIppVIpu+++e9q1+7+n19TUZNq0aRk2bFjZkwQAAAAAaJGK0oqj3DFZueL38OHDkySTJ0/O0KFDs9pqq9Wd69ChQ9Zdd92MGDGirAkCAAAAALRUpWLFUe6YrGTx+6yzzkpNTU3WXXfd7LHHHunbt29j5QUAAAAAAA22UsXvJGnbtm2OOuqovPjii42RDwAAAABA69EYN6hsJp3f+++//ye+9rbbblvp+Ctd/E6SzTbbLH/5y18yYMCAhjwdAAAAAIBWrlu3bo0av0HF7/POOy8nnXRSzj333Gy77bbp0qVLvfPV1dVlSQ4AAAAAgJbp2muvbdT4DSp+77XXXkmS/fbbL6XS/905tCiKlEql1NTUlCc7AAAAAABogAYVvx988MFy5wEAAAAA0OqUkpTKPKO79PGXNAlbb711vebqf+VPf/rTSsdvUPF70KBBDXkaAAAAAAAkSYYPH96o8RtU/E6SOXPm5Gc/+1lefPHFJMmmm26ab3/7240+pBwAAAAAoMUoSiuOcsdsBs4666xGjd+mIU966qmnst566+VHP/pRZs+endmzZ+eHP/xh1ltvvQa1nwMAAAAAtEpFIx3N0Jw5c/If//EfGTt2bGbPnp1kxbiTN998s0HxGtT5PXr06Oy333756U9/mnbtVoRYvnx5/t//+3854YQT8vDDDzcoGQAAAAAAWp9nn302Q4YMSbdu3fLaa6/liCOOSI8ePXLbbbdl+vTpueGGG1Y6ZoM7v0899dS6wneStGvXLqecckqeeuqphoQEAAAAAGh9dH4nScaMGZPDDjssU6dOTceOHevW99prrwY3Wzeo+F1dXZ3p06d/YH3GjBnp2rVrgxIBAAAAAKB1evLJJ3PUUUd9YH3NNdfMzJkzGxSzQcXvAw88MIcffnj++7//OzNmzMiMGTNy88035//9v/+Xr33taw1KBAAAAACgtSkVjXM0N1VVVZk3b94H1l9++eX07NmzQTEbNPP7+9//fkqlUg455JAsX748SdK+ffscffTRufDCCxuUCAAAAAAArdN+++2Xc845J7fcckuSpFQqZfr06Tn11FMzYsSIBsVsUOd3hw4dctlll+Xdd9/N5MmTM3ny5MyePTs/+tGPUlVV1aBEAAAAAABaHTO/kyQ/+MEPMn/+/PTq1SuLFi3KoEGDsv7666dr1645//zzGxSzQZ3f7+ncuXO6d+9e92cAAAAAAFhZ3bp1y7333ps//OEPeeaZZzJ//vxss802GTJkSINjNqjze/ny5Rk3bly6deuWddddN+uuu266deuWM844I8uWLWtwMgAAAAAArUoT6fx++OGHs++++6Zfv34plUq5/fbb650/7LDDUiqV6h3Dhg2rd83s2bNz8MEHp7q6Ot27d8/hhx+e+fPnr1QeO+20U4455piccsopn6rwnTSw+H3sscfm3//933PxxRdn0qRJmTRpUi6++OL87Gc/y3HHHfepEgIAAAAAaC2ayg0vFyxYkC233DJXXnnlR14zbNiw/PWvf607fvGLX9Q7f/DBB+f555/Pvffem7vuuisPP/xwjjzyyH/59z7wwAPZZJNNPvRml3Pnzs2mm26aRx55ZOVfUBo49uSmm27KzTffnD333LNubYsttkj//v3zta99LVdffXWDkgEAAAAAYNXbc88969V7P0xVVVX69OnzoedefPHF3H333XnyySez3XbbJUmuuOKK7LXXXvn+97+ffv36fejzLr300hxxxBGprq7+wLlu3brlqKOOyg9/+MN88YtfXMlX1MDO76qqqqy77rofWB8wYEA6dOjQkJAAAAAAAK1PUWqcI8m8efPqHUuWLPlUqT700EPp1atXNtxwwxx99NH529/+VnfuscceS/fu3esK30kyZMiQtGnTJhMnTvzImM8888wHxqe83x577JGnn366Qfk2qPg9atSonHvuufW+WEuWLMn555+fUaNGNSgRAAAAAADKp3///unWrVvdMX78+AbHGjZsWG644Ybcf//9ueiiizJhwoTsueeeqampSZLMnDkzvXr1qvecdu3apUePHpk5c+ZHxp01a1bat2//kefbtWuXd955p0E5N2jsyaRJk3L//fdnrbXWypZbbplkRYV+6dKl2X333bP//vvXXXvbbbc1KDEAAAAAgBavgTeo/NiYSWbMmFFvnEhVVVWDQx500EF1f958882zxRZbZL311stDDz2U3XffvcFx11xzzTz33HNZf/31P/T8s88+m759+zYodoOK3927d8+IESPqrfXv379BCQAAAAAAUH7V1dUfOku7HD772c9mjTXWyCuvvJLdd989ffr0ydtvv13vmuXLl2f27NkfOSc8Sfbaa6+MGzcuw4YNS8eOHeudW7RoUc4666zss88+DcqxQcXva6+9tkF/GQAAAAAA/6dUrDjKHbOxvfHGG/nb3/5W15U9cODAzJkzJ08//XS23XbbJMkDDzyQ2tra7LDDDh8Z54wzzshtt92Wz33ucxk1alQ23HDDJMlLL72UK6+8MjU1Nfnud7/boBwbVPx+zzvvvJMpU6YkSTbccMP07Nnz04QDAAAAAKAC5s+fn1deeaXu8bRp0zJ58uT06NEjPXr0yPe+972MGDEiffr0yauvvppTTjkl66+/foYOHZok2XjjjTNs2LAcccQRueaaa7Js2bKMGjUqBx10UPr16/eRf2/v3r3zxz/+MUcffXTGjh2bolhRuS+VShk6dGiuvPLK9O7du0GvqUHF7wULFuTYY4/NDTfckNra2iRJ27Ztc8ghh+SKK65I586dG5QMAAAAAECr0ogzv1fGU089lcGDB9c9HjNmTJLk0EMPzdVXX51nn302119/febMmZN+/fpljz32yLnnnltvjviNN96YUaNGZffdd0+bNm0yYsSIXH755R/7d6+zzjr53e9+l3fffTevvPJKiqLIBhtskM985jMr/0Lep0HF7zFjxmTChAm58847s9NOOyVJHn300Rx33HE58cQTc/XVV3+qpAAAAAAAWHV23XXXuq7rD3PPPfd8bIwePXrkpptuanAOn/nMZ7L99ts3+Pn/rEHF71/96le59dZbs+uuu9at7bXXXunUqVMOOOAAxW8AAAAAgE+iEWZ+l72TvJlqUPF74cKFHzpnpVevXlm4cOGnTgoAAAAAoFVoImNPWqI2DXnSwIEDc9ZZZ2Xx4sV1a4sWLcr3vve9DBw4sGzJAQAAAABAQzSo8/vSSy/NsGHDstZaa2XLLbdMkjzzzDPp2LHjJ5r9AgAAAABAdH43ogYVvzfffPNMnTo1N954Y1566aUkyde+9rUcfPDB6dSpU1kTBAAAAACg5bnjjjs+8bX77bffSsdf6eL3smXLstFGG+Wuu+7KEUccsdJ/IQAAAAAAK5Qa4YaXZb+BZiMZPnz4J7quVCqlpqZmpeOvdPG7ffv29WZ9AwAAAADAyqqtrW3U+A264eXIkSNz0UUXZfny5eXOBwAAAAAAPrUGzfx+8sknc//99+f3v/99Nt9883Tp0qXe+dtuu60syQEAAAAA0DosWLAgEyZMyPTp07N06dJ654477riVjteg4nf37t0zYsSIhjwVAAAAAID3FP84yh2zmZk0aVL22muvLFy4MAsWLEiPHj3yv//7v+ncuXN69erV+MXv2traXHLJJXn55ZezdOnS7Lbbbjn77LPTqVOnlf6LAQAAAABau9Z8w8v3Gz16dPbdd99cc8016datWx5//PG0b98+3/jGN3L88cc3KOZKzfw+//zzc/rpp2e11VbLmmuumcsvvzwjR45s0F8MAAAAAABJMnny5Jx44olp06ZN2rZtmyVLlqR///65+OKLc/rppzco5koVv2+44YZcddVVueeee3L77bfnzjvvzI033tjod+UEAAAAAGixijIfzVD79u3Tps2KcnWvXr0yffr0JEm3bt0yY8aMBsVcqbEn06dPz1577VX3eMiQISmVSnnrrbey1lprNSgBAAAAAABat6233jpPPvlkNthggwwaNChnnnlm/vd//zf/+Z//mc0226xBMVeq83v58uXp2LFjvbX27dtn2bJlDfrLAQAAAABatXJ3fTfT7u8LLrggffv2TbJi/PZnPvOZHH300XnnnXfyk5/8pEExV6rzuyiKHHbYYamqqqpbW7x4cb7zne+kS5cudWu33XZbg5IBAAAAAKD12W677er+3KtXr9x9992fOuZKdX4feuih6dWrV7p161Z3fOMb30i/fv3qrQEAAAAA8PFKReMczc1uu+2WOXPmfGB93rx52W233RoUc6U6v6+99toG/SUAAAAAAPBRHnrooSxduvQD64sXL84jjzzSoJgrVfwGAAAAAKCMGmNGdzPq/H722Wfr/vzCCy9k5syZdY9rampy9913Z80112xQbMVvAAAAAIAKaYwxJc1p7MlWW22VUqmUUqn0oeNNOnXqlCuuuKJBsRW/AQAAAACoiGnTpqUoinz2s5/NE088kZ49e9ad69ChQ3r16pW2bds2KLbiNwAAAABApbTysSfrrLNOkqS2trbssduUPWIjuvDCC1MqlXLCCSfUrS1evDgjR47M6quvntVWWy0jRozIrFmzKpckAAAAAAAr7dVXX82xxx6bIUOGZMiQITnuuOPy6quvNjhesyl+P/nkk/nJT36SLbbYot766NGjc+edd+aXv/xlJkyYkLfeeiv7779/hbIEAAAAAFgJRSMdzcw999yTTTbZJE888US22GKLbLHFFpk4cWI23XTT3HvvvQ2K2SzGnsyfPz8HH3xwfvrTn+a8886rW587d25+9rOf5aabbqobhn7ttddm4403zuOPP54dd9yxUikDAAAAAPAJnXbaaRk9enQuvPDCD6yfeuqp+dKXvrTSMZtF5/fIkSOz9957Z8iQIfXWn3766Sxbtqze+kYbbZS11147jz322EfGW7JkSebNm1fvAAAAAABY1UpF4xzNzYsvvpjDDz/8A+vf/va388ILLzQoZpMvft98883505/+lPHjx3/g3MyZM9OhQ4d079693nrv3r0zc+bMj4w5fvz4dOvWre7o379/udMGAAAAAOAT6tmzZyZPnvyB9cmTJ6dXr14Nitmkx57MmDEjxx9/fO6999507NixbHHHjh2bMWPG1D2eN2+eAjgAAAAAsOo1xozuZtT5fc455+Skk07KEUcckSOPPDJ/+ctf8oUvfCFJ8oc//CEXXXRRvVruymjSxe+nn346b7/9drbZZpu6tZqamjz88MP58Y9/nHvuuSdLly7NnDlz6nV/z5o1K3369PnIuFVVVamqqmrM1AEAAAAAPl4rL35/73vfy3e+852MGzcuXbt2zQ9+8IOMHTs2SdKvX7+cffbZOe644xoUu0kXv3fffff8+c9/rrf2rW99KxtttFFOPfXU9O/fP+3bt8/999+fESNGJEmmTJmS6dOnZ+DAgZVIGQAAAACAT6goVlTqS6VSRo8endGjR+fvf/97kqRr166fKnaTLn537do1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FVIqGmHsicbvJDq/AQAAAABogZp08Xv8+PHZfvvt07Vr1/Tq1SvDhw/PlClT6l2zePHijBw5MquvvnpWW221jBgxIrNmzapQxgAAAAAAK6FopIOmXfyeMGFCRo4cmccffzz33ntvli1blj322CMLFiyou2b06NG5884788tf/jITJkzIW2+9lf3337+CWQMAAAAAUGlNeub33XffXe/xddddl169euXpp5/OLrvskrlz5+ZnP/tZbrrppuy2225JkmuvvTYbb7xxHn/88ey4444fGnfJkiVZsmRJ3eN58+Y13osAAAAAAPgIpaJIqShvq3a54zVXTbrz+5/NnTs3SdKjR48kydNPP51ly5ZlyJAhdddstNFGWXvttfPYY499ZJzx48enW7dudUf//v0bN3EAAAAAAFapZlP8rq2tzQknnJCddtopm222WZJk5syZ6dChQ7p3717v2t69e2fmzJkfGWvs2LGZO3du3TFjxozGTB0AAAAA4MPVNtJB0x578n4jR47Mc889l0cfffRTx6qqqkpVVVUZsgIAAAAAaDhjTxpPs+j8HjVqVO666648+OCDWWutterW+/Tpk6VLl2bOnDn1rp81a1b69OmzirMEAAAAAKCpaNLF76IoMmrUqPz617/OAw88kAEDBtQ7v+2226Z9+/a5//7769amTJmS6dOnZ+DAgas6XQAAAACAlVM00kHTHnsycuTI3HTTTfnNb36Trl271s3x7tatWzp16pRu3brl8MMPz5gxY9KjR49UV1fn2GOPzcCBA7PjjjtWOHsAAAAAACqlSRe/r7766iTJrrvuWm/92muvzWGHHZYk+dGPfpQ2bdpkxIgRWbJkSYYOHZqrrrpqFWcKAAAAANAARbHiKHdMmnbxu/gEm9SxY8dceeWVufLKK1dBRgAAAAAANAdNuvgNAAAAANCSlYoVR7lj0sRveAkAAAAAAA2h8xsAAAAAoFLM/G40it8AAAAAABVSql1xlDsmxp4AAAAAANAC6fwGAAAAAKgUY08ajc5vAAAAAABaHJ3fAAAAAACVUvzjKHdMdH4DAAAAANDy6PwGAAAAAKiQUlGkVOYZ3eWO11zp/AYAAAAAoMXR+Q0AAAAAUClFseIod0wUvwEAAAAAKqZIUtsIMTH2BAAAAACAlkfnNwAAAABAhbjhZePR+Q0AAAAAQIuj8xsAAAAA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EyZMyMSJEz/wnLPPPjvf+973VmWaAAAAANDizZgxI2uttVal02gWFi9enAEDBmTmzJmNEr9Pnz6ZNm1aOnbs2Cjxm4Nm3/ndEGPHjs2YMWPqHtfW1mb27NlZffXVUyqVKpjZpzdv3rz0798/M2bMSHV1daXT4Z/Yn6bL3jRd9qZpsz9Nl71puuxN02Z/mi5703TZm6bN/jRdLW1viqLI3//+9/Tr16/SqTQbHTt2zLRp07J0aeP8FkmHDh1adeE7aQHF7zXWWCNt27bNrFmz6q3PmjUrffr0+dDnVFVVpaqqqt5a9+7dGyvFiqiurm4R/3C2VPan6bI3TZe9adrsT9Nlb5oue9O02Z+my940XfamabM/TVdL2ptu3bpVOoVmp2PHjq2+QN2Ymv0NLzt06JBtt902999/f91abW1t7r///npjUAAAAAAAaD2afed3kowZMyaHHnpotttuu3z+85/PpZdemgULFuRb3/pWpVMDAAAAAKACWkTx+8ADD8w777yTM888MzNnzsxWW22Vu+++O7179650aqtcVVVVzjrrrA+MdaFpsD9Nl71puuxN02Z/mi5703TZm6bN/jRd9qbpsjdNm/1puuwNNL5SURRFpZMAAAAAAIByavYzvwEAAAAA4J8pfgMAAAAA0OIofgMAAAAA0OIofgMAAAAA0OIofgMAAAAA0OIofkMFFEVR6RQAaAVqamoqnQL/QlEUfiYAAIBGpPgNq9CCBQuSJKVSqcKZ8HFqa2srnQL/gv2Bj/f888/n9NNPz/z58yudCv9k/vz5Wbp0aebOnetngibuvQ+QfJAEn4z3StPmQ1egNVL8bqGWL19e6RT4J5MnT85hhx2WadOmVToVPsTbb7+dl156KRMnTkyStGnjn8emaM6cOUlW7I8CeOW99NJLufnmmyudBh/imWeeyeabb57q6uqsttpqSXxo1FQ899xz2WuvvbLbbrtl8803z/nnn5+XXnqp0mnxIZ5//vnssssumTZtWtq2bauoBx/Dh65Nlw9dmwcfuELjUN1pQZ5//vl85StfycKFC9OuXTsF8CbkmWeeyfbbb58BAwZkwIAB9c755L3ynn322ey666456KCDcuCBB2brrbfOvffe6wf3JubFF1/MNttskzPPPDOJAnilTZ06Ndtvv32+/vWv56qrrqp0OrzPs88+my984Qs55ZRT8t3vfrdu3ful8l555ZXsvvvu2WGHHXL66afnu9/9bsaNG5fjjjsu9957b6XT431ee+21DB8+PBMnTsywYcMUwJsAH7g2bT50bbp86No8+MAVGk+7SidAeUybNi377LNPXn/99QwZMiT33XdfOnfunOXLl6ddO9tcSc8991y+8IUv5NRTT815552XZMX4k0WLFmWNNdbwyXuFvf7669lnn31y+OGH56CDDkqnTp3yzW9+M4ceemhOPfXUHHrooenevXul02z1ZsyYka9//etp165dfv3rX6ddu3Y588wz6wrgOvVXrblz5+ass87KsGHDsskmm2TUqFGpqanJscceW+nUWr3XX389gwcPzl577ZULL7wwSXLOOedkypQpmT17do466qjstdde6dChQ4UzbZ1+/vOfZ+edd84ll1xStzZ16tRcddVVqaqqSlVVVXbZZZcKZkiSLF68OFdeeWW23HLLXHLJJbn66quz++675/7778+AAQNSU1OTtm3bVjrNVuW9D1wXLFiQ2bNn55hjjql0SrzPv/rQ1c9olfXeh66HHHJIBg8enOnTp+eYY47JhAkTcvLJJ+dLX/pSpVMk//eB67Rp0zJs2LDcfffdvt9AGflO1AIsXLgwP/zhD7PtttvmxhtvzNKlSzNo0CAd4E3ArFmzstNOO+ULX/hCXeF75MiRGTp0aHbdddeMGDGiboyDDvDKmDhxYjbYYIOcfPLJWX/99bP22mvnuOOOy+zZs/OTn/wkv/nNb5LYn0oqiiK/+MUv0q9fv1x55ZUZMWJEfvGLX+Scc85JsqIDXGfEqrVw4cL069cvBx98cE4//fRcfPHFOf7443PFFVck8X6ppDfeeCPdunVLt27d8sgjj2TXXXfNhAkTsnz58nTv3j37779/Lr744iT2qRJef/31dO7cOUnqfrtorbXWyuDBg/OXv/wlt9xySxJ7U2kdO3bMNttsk6985SsZPnx4Lrzwwqy//vrZfffddeRVwNy5c3P22Wdn2LBhGTduXEaNGlX3/YbKe/3117Pbbrt94EPXgw8+OPvuu29uv/32LF26tMJZtl7v/9B1r732yne+852MHj06jzzySC6//PI8/PDDlU6x1Xv/B6633npr1l13Xd9voMy0BLcAnTt3zoYbbpiddtopBx54YPr165cTTzwxgwYNyoQJE9K5c2efGFZI796988UvfjFvv/12rr/++lx99dXp2rVr9ttvv3Ts2DFXXXVVdt1110ycODFVVVUpikIn+Co2ZcqUvPLKK3XFiGTFe+ob3/hG3nzzzYwbNy4HHXRQqqqqKphl61YqlXLIIYekd+/e+dKXvpQtt9wySfKLX/wiRVHkrLPOStu2bXUXrQLvvPNOXn/99VRXV+fcc89Np06dkiTHHHNMiqLI8ccfnyR1HeDLly/P3Llzs/rqq1cs59bivb1Ze+21c8stt2TkyJH56le/mu222y4///nPs8Yaa6RNmzYZPHhwjjnmmHzpS1/KDjvsUOm0W4X39qZbt24ZNGhQTj755MyYMSP9+/fPm2++mbPPPjs333xzFi9enAMOOCCjRo3KRhttVOm0W633fhb72te+Vre21VZbZfz48fnud7+b3XbbLffff38++9nPZtGiRXn99dez/vrr+03LRjR//vysueaa2WmnnTJs2LB07dq13vcbPz9X1vTp09O9e/d07949jzzySMaNG5e2bdtmjTXWqPvQ9ZxzzskZZ5xhrypgxowZ6dKlS5IV76XVVlvtAx+67rLLLvamgt77wHWrrbbK8OHDs8466+TUU0/1G0dQTgXNVm1tbbFs2bJ6j4uiKJYtW1Y88MADxbbbbltst912xYIFC4qiKIqFCxcWr732WlFTU1ORfFuT2traYsmSJXWPR4wYUbRt27b48pe/XLz99tt166+//nqx5pprFmPHjq1Emq1WbW1t3fvg2WefLdZaa61i7Nixxd/+9rfi6aefLjp37lxcdtllRVEURf/+/Yuf//znlUy31fuwf7Peeuut4qyzzio22mij4uyzz65bv/322/0b10ief/75Yqeddir22GOP4itf+UqxfPnyeucXLVpUXHTRRUWpVCouv/zyoiiK4rjjjivOOOOMev8eUn7v7c2XvvSl4itf+UpRFEXxu9/9rhgxYkTx8MMP17t24cKFxVprrVX86Ec/qkCmrc8/v29ee+21Yt999y1KpVIxaNCgolOnTsVRRx1VFEVRzJs3r+jfv39x7733Vjhr3vuZuijqfw968skni6FDhxbrrrtu8dJLLxXHHXdcscUWWxTz5s2rRJqtymuvvVb35wULFhQXX3xxve83RbHi/4H+93//txLptXq//e1vi+23377o1atXsffeexezZs2qe+/85Cc/Kdq2bVs8/vjjFc6ydTr33HOLrl271r2H3njjjaK6urr43e9+V9x2221Fu3btihdffLHCWbZe7/9+8/61p556qu77zauvvloUxYqf4V588cV6NSDgk1H8bqamTJlSjBo1qvjKV75SXHzxxXXr7/1DWFNTU68APnv27GLkyJHF4MGD64rhNI7378348ePr1k855ZTiv//7v+tdu2zZsmKnnXYqjjnmmFWdZqv1/v35/ve/X9TU1BQ//OEPi759+xZ9+/YtunbtWpxwwglFUazYn8997nPF97///Qpn3Xr9qx/u3nzzzboC+FlnnVWccMIJRalUKt58881VmGHr8NxzzxXdu3cvTj/99OL111//yA8YFi1aVFx88cVFhw4dih122KEolUrFn/70p1Wcbevyz3vz/vfMq6++WixatKgoiv/7n6sZM2YU22yzTXHXXXdVJN/W5P178/7C3dy5c4uf/exnxWWXXVbccsstdesvvvhisdFGGxVPPvlkJdJt1V588cXiF7/4xUeef39x4qmnnir23HPPolQqFV27di0mTpy4KlJsdRYsWFC88847xf3331+88cYbxdy5c4uiKOo+ePWBa2W9tz/33Xdf8cYbbxRFURSPPfZYMXz48GLChAn1rvWh66r1z++d559/vjjkkEOKUqlUfPGLX/ShaxPkA1dofIrfzdDkyZOLnj17FsOHDy8OOuigon379sUll1xSd/69fzDfK4B//vOfL6qqqoouXbr4Ab2RfdjeXHDBBXXn3ytCvGfJkiXFPvvsU/fD4Id98kv5/PP+tGvXrrjyyiuLoljRhf+73/2uePTRR+uunzt3brHbbrsVv/zlLyuVcqv03HPPFcOHD6/7oO7DCuDvvVfeeuut4swzzyxKpVLxmc98pnjqqadWaa6twd/+9rdi5513Lo477rh66x/179WcOXOKbbbZpujRo0fx7LPProoUW62P2pt/7sp/v+9+97vFJptsUlesoHF81N78K6eeemqx6aabFrNmzWrEzPhnL7/8crHaaqsVpVKp7meCf2XJkiXFl7/85aJHjx7F888/vwoybH2mTJlSHHLIIcVGG21UdOzYsejevXvx9a9//QMfDPnAtTL+eX+6du1afP3rXy+mTp1aLFiwoO7nNx+6rnrv35uqqqqiR48exde//vXivvvuK377298WP/rRj+o1Y/nQtTJ84AqrnuF0zcyzzz6bgQMHZvTo0Tn//PNTW1ubNdZYI2+++WYWL16cjh071s28bdOmTXbcccesvvrq6dKlSx5++OFsuummFX4FLddH7c3bb7+dhQsXpnPnzunYsWPd9bW1tTn33HMzadKkXHbZZUlizloj+qj9efnll7No0aKsvfbaWXvtteuuX7JkScaPH58pU6bk85//fAUzb12mTZuWffbZJ6+//nqGDBmS++67L507d87y5cvrzVN9773St2/fTJs2LV27ds2jjz6aTTbZpFKpt1gzZ87MX//614wYMaLeXPX39qB434zI5cuX57zzzsukSZPyzDPPZPPNN69Y3q3BR+3NezMh3783v/3tb/Ob3/wmt956ax544IGsueaaFcu7NfiovXnP+/dmwoQJueWWW/Jf//Vfeeihh9KrV69KpNwqzZ07N2eddVaGDRuWTTbZJKNGjUpNTU3dfQv+WU1NTX784x/n97//ff7whz/4ntMInn322QwbNixf/vKXc9ppp2WHHXbIddddl1/96lf55je/mf/4j//ITjvtlGTFnNwjjzwyN998c6ZOner7zirwUfvzy1/+Mvvuu29+/vOfZ+DAgUn+7+eEa665JosXL85WW21Vwcxbvg/bm5///Oe5/fbb8/TTT+e//uu/stdee9V7znXXXZe2bdvW+38gGtfUqVOz/fbbZ8GCBZk9e3aOOeaYD1zz/prA5ptvng4dOuQzn/lMHnnkEd93oKEqXHxnJUyfPr1YY401iq9+9av11g888MBiq622KjbaaKNi2LBhxfXXX1937oILLig6dOhQTJo0aRVn27p8kr3Zc8896/bm4YcfLr761a8WvXr10qGyCvyr/dlyyy3r3jvXXXddURRF8fTTTxcHH3xw0bt3b/uzCi1YsKAYNWpUMWLEiOKmm276wH0LPqwD/Kc//WnRvXt3+9SIbrzxxqJdu3Z1XSgfNvJkwYIFxVNPPVXU1tYWJ554YjF58uRVnWar9En35qGHHip+85vfFLvssotu/FXkk+7Nn//852LGjBnF6NGjixdeeGFVp9nqvfXWW8WJJ55Y/PrXvy4WL15cXHLJJfXGaHzYb7jccsstxUsvvbSqU20VnnnmmaJz587F2LFjP/A9/7//+7+Lrbfeuvj85z9fTJ06tSiKFe+rk08+uSiVSv5tWwU+6f688sorRVGsmAN+5JFHFp/5zGf8v2gj+1d7c/PNNxdbbbVV8fnPf754+eWXi6IoigkTJhSjRo0qqqur/Qy9Cs2ZM6f4+te/Xvzbv/1b3W+uvv++Bf9s+fLlxQ9+8IOiU6dO9gk+pTYfXx6nqaipqcmAAQOyZMmS/OEPf0iSXHjhhbnzzjszYsSInHTSSXn99ddz3nnn5ZlnnkmS9OjRI5MnT/ZJeyP7JHvz2muv5bzzzsvEiRNTFEV69uyZBx98MFtvvXWFs2/5/tX+/Nu//Vvde+f888/P888/n2222SZf/OIX88gjj9ifVahz587ZcMMN82//9m856KCD8oMf/CBFUWTQoEFZuHBh2rVrl5qamnrP2WefffKnP/3JPjWiddddN+3atcttt92WJB/oYE2Sn//85xk7dmxKpVLOP//8bLnllqs6zVbpk+zNtddem/PPPz9DhgzJnXfeqStyFfmk75sxY8ZkrbXWyoUXXpiNN954VafZar3zzjt56qmn8ve//z3nnntuhg8fnqqqqhxzzDG56KKLcvzxx+eKK66o91st77zzTpLkq1/9ajbccMNKpt8izZgxI7vvvnv23nvvXHDBBWnXrl2Kosjy5cuTJAcccECOPvrovPTSS3nwwQeTJLNmzUptbW0mTZrk37ZGtjL788ADD2T58uV5880389JLL2XChAn+X7QRfdzeHHjggTnmmGPy0ksv5aGHHkqSdOnSJR06dMjjjz/uZ+hVaP78+VlzzTXzjW98I6effnouvvjiuu83yYrfCnu/tm3bpn///pk0aZJ9gk+pVPzzO4wmberUqTnuuOPSoUOH9OrVK3fccUf+8z//M3vssUeSZPr06Vl33XVz1VVX5Tvf+U6Fs21dPune/Md//Ee+/e1vZ+nSpenQoUOFs249Pun+/PjHP/7QXz+j8RRFkZqamrqxJsU/xgEsX748jzzySE4++eSUSqVMmDAhnTt3zqJFi/L222+nX79+ad++fYWzb/nefPPNbLPNNtlxxx1z+eWXZ5111klSf2zDSSedlHbt2mX8+PHGN61Cn2RvTjzxxHTo0CEXXHCBvVmFPun7pm3btrnwwgvtzSr0wgsv5Mgjj0yXLl3SpUuX/PKXv6wbFZQkixcvzuWXX57TTjstl112WY499tgcf/zxqa6uzrhx4/zs1khee+21HHDAAenbt29OPvnk7LzzznXn3v++GTRoUHr27Jlbb701Sfw8vYqszP706tUrv/zlL7N8+fIsXLgw1dXVlUq7VViZvVljjTXyq1/9Kon3TqW8/vrrdT8TLFy4MFdeeWVOPfXUuu83yYoPXN9999307NmzkqlCi6Lzu5nZYIMNctlll2XRokW58cYbc8opp2SPPfZIURRZtmxZ2rZtmy222CJrrLFGkg9+ekjj+SR7s/nmm9f9AOiHjVXrk7533pu16r2zarz88ss57rjjcsABB+SSSy5JkrrCd7t27TJo0KBccskldR3g7777bk4++eR861vfyrJlyyqcfeuw5ppr5uqrr84999yTcePG5YUXXkiyYp8WLlyY008/Pbfeemu+/e1vK+CtYp9kb371q1/lsMMOszer2Cd93xx++OH2ZhV6/vnns9NOO2XQoEH56U9/mltvvbVe4TtZMUf6uOOOy0UXXZSTTjopO+64Y6644orsv//+fnZrROuuu25uvPHGLF26NOedd14effTRD72uTZs2qaqqqntsT1aNldmf9/akXbt2Ct+rwMrszfvvP+W9s2osXLgw//u//5sHHnggb775Zj7zmc8kWfGbyZ07d86xxx6bCy+8sF4H+IknnpjLL788S5curWTq0LKsyhkrlM8rr7xS7LHHHsWee+5ZPPzww3Xr48aNKwYMGFBMnz69gtm1bvamabM/TcfkyZOLnj17FsOHDy8OOuigon379sUll1xSd/69Gbk1NTXFAw88UHz+858vqqqqii5durjT+SpWU1NTXHPNNUW7du2KjTbaqPjWt75VHH300cV+++3n3gUVZm+aLnvTtPztb38rdt555+K4446rt/5hc72LYsVs1m222abo0aOHedKr0Msvv1wMGzasGDp0aPHoo4/WrdfU1BQzZswo9txzz7p7tHzU3tF47E/TZW+anilTphSHHHJIsdFGGxUdO3YsunfvXnz9618vnnzyyXrXLVq0qLj44ouLDh06FDvssENRKpX8jABlpvO7mVpvvfXy4x//OEVR5Pzzz8+kSZNy8cUX55JLLsmvfvWr9O/fv9Iptlr2pmmzP03Ds88+m4EDB+aII47Ir3/969x444056qij8uabb2bx4sVJ/m9Gbps2bbLjjjtm9dVXT5cuXTJx4sR8/vOfr2T6rU6bNm1y1FFH5Q9/+EM222yzTJo0Kc8991w23njjPProo+YQVpC9abrsTdMyc+bM/PWvf82IESNSW1tbt/5e533xvt/4Wr58ec4777xMmjQpDz30kHnSq9AGG2yQyy+/PKVSKeeee25dF2ubNm3y4x//OG+99VZ23333JPFbExVgf5oue9O0PPvss9l1113TuXPnnHbaaZk0aVKOOuqoPPHEE/nmN79Zdx+qZMVvHB155JHZbLPNMnXq1DzzzDN+RoAyM/O7mZs6dWrGjBmTJ554Iu+++24ee+yxbLvttpVOi9ibps7+VM6MGTOyzTbbZPDgwbnlllvq1g866KBMmTIlixcvzrrrrpuvfe1rOeSQQ5Ik48ePz9lnn52JEye6aVKF1dTUfGBMAE2DvWm67E3l3XTTTTn00EOzdOnSlEql1NbWfuBGpAsXLsyLL76YbbbZJieffHK++c1vuoFvhbx3r5aiKDJ+/Pjce++9dQU9e1J59qfpsjeV916Tz/HHH59zzjmn7r5GSXLLLbfkwgsvTPv27XPjjTdm/fXXT21tbU477bR8//vfzzPPPOMDV2gEOr+buQ022CDf//73s+OOO2bSpEmKd02IvWna7E/l1NTUZMCAAVmyZEld18OFF16YO++8MyNGjMhJJ52U119/Peedd16eeeaZJEmPHj0yefJkhe8m4P3FIp+fNy32pumyN5W37rrrpl27drntttuS5AOF7yT5+c9/nrFjx6ZUKuX8889XKKqg97pY27dvn2HDhuWMM87IQw89ZE+aCPvTdNmbypoxY0Z233337L333rngggvSrl27FEWR5cuXJ0kOOOCAHH300XnppZfy4IMPJklmzZqV2traTJo0SeEbGonO7xZi2bJlad++faXT4EPYm6bN/lTGe10pHTp0SK9evXLHHXfkP//zP7PHHnskSaZPn5511103V111Vb7zne9UOFsAmrs333wz22yzTXbcccdcfvnlWWeddZKs+DDivREAJ510Utq1a5fx48cbC9BETJkyJaecckouuOCCbLrpppVOh39if5oue1MZr732Wg444ID07ds3J598cnbeeee6c+//fjNo0KD07Nkzt956a5Jk6dKlbkIKjUjndwuheNd02Zumzf5UxgYbbJDLLrssixYtyo033phTTjkle+yxR4qiyLJly9K2bdtsscUWWWONNZLolATg01lzzTVz9dVX55577sm4cePywgsvJFkx+3bhwoU5/fTTc+utt+bb3/62wncTsuGGG+bWW29VvGui7E/TZW8qY911182NN96YpUuX5rzzzqubvf7P2rRpk6qqqrrHCt/QuHR+A1Axr776ao455pi0bds2Y8eOzRe/+MUkyZlnnpn/+q//yoQJE9yEFICyqK2tzU9/+tOMGjUq66+/fgYOHJiOHTvmzTffzOOPP567777bTcYA+NTeP3t93Lhx2WmnnZKs+D701ltv5cgjj8yBBx6YQw89tF5HONA4FL8BqKgPuzHPWWedlT/+8Y+KEACU3RNPPJFLLrkkr7zySrp27ZovfOELOfzww7PBBhtUOjUAWoj3/z/OGWecUTcC5bTTTsvdd9+du+66K2uttVaFs4TWQfEbgIqbOnVqxowZkyeeeCLvvvtuHnvsMTchBaDR1NTUpG3btpVOA4AW7MOafM4999w8+uijbkIKq5DiNwBNghvzALCqvP/XzP3KOQCNRZMPVJ7iNwBNxrJly9yEFAAAaDE0+UBlKX4DAAAAQCPR5AOVo/gNAAAAAECL06bSCQAAAAAAQLkpfgMAAAAA0OIofgMAAAAA0OIofgMAAAAA0OIofgMAAAAA0OIofgMAAAAA0OIofgMA0Kw99NBDKZVKmTNnTpLkuuuuS/fu3SuaEwAAUHmK3wAArDLXXHNNunbtmuXLl9etzZ8/P+3bt8+uu+5a79r3itqvvvrqKs4SAABoCRS/AQBYZQYPHpz58+fnqaeeqlt75JFH0qdPn0ycODGLFy+uW3/wwQez9tprZ7311qtEqgAAQDOn+A0AwCqz4YYbpm/fvnnooYfq1h566KF8+ctfzoABA/L444/XWx88eHBqa2szfvz4DBgwIJ06dcqWW26ZW2+9tQLZAwAAzYniNwAAq9TgwYPz4IMP1j1+8MEHs+uuu2bQoEF164sWLcrEiRMzePDgjB8/PjfccEOuueaaPP/88xk9enS+8Y1vZMKECZV6CQAAQDPQrtIJAADQugwePDgnnHBCli9fnkWLFmXSpEkZNGhQli1blmuuuSZJ8thjj2XJkiXZdddds8kmm+S+++7LwIEDkySf/exn8+ijj+YnP/lJBg0aVMmXAgAANGGK3wAArFK77rprFixYkCeffDLvvvtuPve5z6Vnz54ZNGhQvvWtb2Xx4sV56KGH8tnPfjbz58/PwoUL86UvfalejKVLl2brrbeu0CsAAACaA8VvAABWqfXXXz9rrbVWHnzwwbz77rt13dv9+vVL//7988c//jEPPvhgdtttt8yfPz9J8tvf/jZrrrlmvThVVVWrPHcAAKD5UPwGAGCVGzx4cB566KG8++67Ofnkk+vWd9lll/zP//xPnnjiiRx99NHZZJNNUlVVlenTpxtxAgAArBTFbwAAVrnBgwdn5MiRWbZsWb2i9qBBgzJq1KgsXbo0gwcPTteuXXPSSSdl9OjRqa2tzc4775y5c+fmD3/4Q6qrq3PooYdW8FUAAABNmeI3AACr3ODBg7No0aJstNFG6d27d936oEGD8ve//z0bbrhh+vbtmyQ599xz07Nnz4wfPz5/+ctf0r1792yzzTY5/fTTK5U+AADQDJSKoigqnQQAAAAAAJRTm0onAAAAAAAA5ab4DQAAAABAi6P4DQAAAABAi6P4DQAAAABAi6P4DQAAAABAi6P4DQAAAABAi6P4DQAAAABAi6P4DQAAAABAi6P4DQAAAABAi6P4DQAAAABAi6P4DQAAAABAi/P/AffJrkaYU+drAAAAAElFTkSuQmCC", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "\n", "Number of wells in the top 25%: 3\n", "Wells in the top 25% of highest outlier proportions:\n", "B5, C5, D5\n" ] } ], "source": [ "# Instantiate the ContaminationDetector class and run the contamination detection process\n", "detector = ContaminationDetector(\n", " dataframe=filtered_nf1_df, nucleus_channel_naming=\"DAPI\"\n", ").run()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In this example, we can see that the detector has found anomalous texture surrounding the nucleus from this plate. This is a problem and could likely reflect contamination.\n", "\n", "In step 2, based on the mean of the texture, it was found that this problem only impacts part of the plate.\n", "\n", "In step 3, we found 3 wells that have high proportion of outlier single-cells with abnormal texture. This was concluded to be one cell line that had mycoplasma contamination on the plate, while the rest of the cell lines were fine." ] } ], "metadata": { "kernelspec": { "display_name": "cosmicqc-vNopUmqk-py3.11", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.11.9" } }, "nbformat": 4, "nbformat_minor": 2 }