diff --git a/docs/conf.py b/docs/conf.py index 64f3bdb..5242ac3 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -141,6 +141,7 @@ ("py:class", "keras.src.losses.loss.Loss"), ("py:class", "keras.src.metrics.metric.Metric"), ("py:class", "seaborn.matrix.ClusterGrid"), + ("py:class", "pysam.libcfaidx.FastaFile"), ] suppress_warnings = [ diff --git a/docs/tutorials/enhancer_code_analysis.ipynb b/docs/tutorials/enhancer_code_analysis.ipynb index f6bc93a..729a702 100644 --- a/docs/tutorials/enhancer_code_analysis.ipynb +++ b/docs/tutorials/enhancer_code_analysis.ipynb @@ -284,21 +284,21 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "2024-10-09T14:44:14.663438+0200 INFO Starting genomic contributions plot for classes: ['Astro', 'L5ET', 'Vip', 'Oligo']\n" + "2024-11-03T12:34:46.917516+0100 INFO Starting genomic contributions plot for classes: ['Astro', 'L5ET', 'Vip', 'Oligo']\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ - "/data/projects/c04/cbd-saerts/nkemp/software/CREsted/src/crested/pl/_utils.py:80: UserWarning: The figure layout has changed to tight\n", + "/home/VIB.LOCAL/niklas.kempynck/.conda/envs/crested/lib/python3.11/site-packages/crested/pl/_utils.py:95: UserWarning: The figure layout has changed to tight\n", " plt.tight_layout()\n" ] }, @@ -315,6 +315,7 @@ ], "source": [ "%matplotlib inline\n", + "top_k=1000\n", "crested.pl.patterns.modisco_results(\n", " classes=[\"Astro\", \"L5ET\", \"Vip\", \"Oligo\"],\n", " contribution=\"positive\",\n", @@ -942,19 +943,24 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ - "/data/projects/c04/cbd-saerts/nkemp/software/CREsted/src/crested/tl/modisco/_tfmodisco.py:1167: FutureWarning: The default of observed=False is deprecated and will be changed to True in a future version of pandas. Pass observed=False to retain current behavior or observed=True to adopt the future default and silence this warning.\n", + "2024-11-03 11:13:55.180753: I tensorflow/core/util/port.cc:113] oneDNN custom operations are on. You may see slightly different numerical results due to floating-point round-off errors from different computation orders. To turn them off, set the environment variable `TF_ENABLE_ONEDNN_OPTS=0`.\n", + "2024-11-03 11:13:55.219549: I tensorflow/core/platform/cpu_feature_guard.cc:210] This TensorFlow binary is optimized to use available CPU instructions in performance-critical operations.\n", + "To enable the following instructions: AVX2 AVX512F AVX512_VNNI AVX512_BF16 AVX512_FP16 AVX_VNNI AMX_TILE AMX_INT8 AMX_BF16 FMA, in other operations, rebuild TensorFlow with the appropriate compiler flags.\n", + "2024-11-03 11:13:59.266692: W tensorflow/compiler/tf2tensorrt/utils/py_utils.cc:38] TF-TRT Warning: Could not find TensorRT\n", + "/home/VIB.LOCAL/niklas.kempynck/.conda/envs/crested/lib/python3.11/site-packages/crested/tl/modisco/_tfmodisco.py:1167: FutureWarning: The default of observed=False is deprecated and will be changed to True in a future version of pandas. Pass observed=False to retain current behavior or observed=True to adopt the future default and silence this warning.\n", " mean_expression_per_cell_type: pd.DataFrame = gene_expression_df.groupby(\n" ] } ], "source": [ + "import crested\n", "file_path = \"/home/VIB.LOCAL/niklas.kempynck/nkemp/mouse/biccn/Mouse_rna.h5ad\" # Locate h5 file containing scRNAseq data\n", "cell_type_column = \"subclass_Bakken_2022\"\n", "mean_expression_df = crested.tl.modisco.calculate_mean_expression_per_cell_type(\n", @@ -964,638 +970,38 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 3, "metadata": {}, "outputs": [ { "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", - " \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", - " \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", - " \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", - "
Xkr4Gm1992Gm19938Gm37381Rp1Sox17Mrpl15Lypla1Tcea1Rgs20...AC132444.5CsprsGm12406Gm6313Gm45121Gm47020Gm48133Nhlrc4Dsg1cErcc6l
subclass_Bakken_2022
Astro2.0650160.0024080.0051600.0000000.0010320.0006880.0519440.2318540.2555905.739250...0.000000.0000000.0010320.000000.0000000.0000000.000000.0000000.0000000.000000
Endo3.5431750.0083570.0139280.0055710.0306410.2423400.0306410.1866300.2869080.286908...0.000000.0000000.0000000.000000.0000000.0000000.000000.0000000.0000000.000000
L2/3 IT4.7874370.1737330.1721630.0008570.0051390.0000000.1240540.1947180.3804431.034119...0.000000.0000000.0002860.000000.0002860.0001430.000000.0000000.0000000.000000
L5 ET2.5520230.0809250.1127170.0000000.0144510.0000000.1329480.1618500.2976880.343931...0.000000.0000000.0000000.000000.0000000.0000000.000000.0000000.0000000.000000
L5 IT7.3317200.2364720.2420810.0002200.0049490.0000000.0962380.1856580.3545970.436538...0.000220.0000000.0000000.000110.0001100.0000000.000110.0000000.0000000.000000
L5/6 NP10.8301370.2410960.2616440.0000000.0041100.0000000.0849320.1109590.3794520.083562...0.000000.0000000.0000000.000000.0000000.0000000.000000.0000000.0000000.000000
L6 CT11.6859290.3074940.3345080.0000000.0046980.0000000.1146350.1808790.3984030.722340...0.000000.0002350.0000000.000000.0000000.0000000.000470.0002350.0004700.000000
L6 IT8.8518900.2676200.2665990.0000000.0030640.0000000.0919310.1460670.3718080.432074...0.000000.0000000.0000000.000000.0000000.0000000.000000.0000000.0000000.001021
L6b12.1911260.3720140.3788400.0000000.0068260.0000000.1228670.2013650.4266211.911263...0.000000.0000000.0000000.000000.0000000.0000000.000000.0000000.0000000.000000
Lamp515.7445480.3530630.4122530.0000000.0051920.0000000.1028040.1277260.4143300.063344...0.000000.0000000.0000000.000000.0000000.0000000.000000.0000000.0000000.000000
Micro-PVM3.5916670.0048610.0006940.0006940.0000000.0000000.0395830.1361110.2326390.277431...0.000000.0000000.0000000.000000.0000000.0000000.000000.0000000.0000000.000000
OPC4.6418600.0465120.0697670.0000000.0000000.0000000.0837210.1767440.3116281.209302...0.000000.0000000.0000000.000000.0000000.0000000.000000.0000000.0000000.000000
Oligo5.5386250.0369800.0474350.0000000.0011620.0000000.0404650.1293320.2491770.124685...0.000000.0000000.0000000.000000.0000000.0000000.000000.0000000.0003870.000194
Pvalb18.2905240.4825440.5405240.0006230.0199500.0012470.1209480.2899000.4744390.115337...0.000000.0000000.0000000.000000.0000000.0000000.000000.0000000.0000000.000000
Sncg8.0170940.2222220.3162390.0000000.0000000.0000000.1196580.1794870.4615380.324786...0.000000.0000000.0000000.000000.0000000.0000000.000000.0000000.0000000.000000
Sst21.6253300.5083550.5787160.0000000.0061570.0000000.0932280.2049250.4019350.294635...0.000000.0000000.0000000.000000.0000000.0000000.000000.0000000.0000000.000000
Sst Chodl20.0535720.6428570.4285710.0000000.0000000.0000000.0714290.1785710.5357140.089286...0.000000.0000000.0000000.000000.0000000.0000000.000000.0000000.0000000.000000
VLMC2.6230770.0019230.0019230.0038460.0519230.0057690.0769230.2307690.4269230.296154...0.000000.0000000.0000000.000000.0000000.0000000.000000.0000000.0000000.000000
Vip10.4674560.2792900.2579880.0000000.0023670.0000000.0792900.1408280.3230770.125444...0.000000.0000000.0011830.000000.0011830.0000000.000000.0000000.0000000.000000
\n", - "

19 rows × 24275 columns

\n", - "
" - ], "text/plain": [ - " Xkr4 Gm1992 Gm19938 Gm37381 Rp1 \\\n", - "subclass_Bakken_2022 \n", - "Astro 2.065016 0.002408 0.005160 0.000000 0.001032 \n", - "Endo 3.543175 0.008357 0.013928 0.005571 0.030641 \n", - "L2/3 IT 4.787437 0.173733 0.172163 0.000857 0.005139 \n", - "L5 ET 2.552023 0.080925 0.112717 0.000000 0.014451 \n", - "L5 IT 7.331720 0.236472 0.242081 0.000220 0.004949 \n", - "L5/6 NP 10.830137 0.241096 0.261644 0.000000 0.004110 \n", - "L6 CT 11.685929 0.307494 0.334508 0.000000 0.004698 \n", - "L6 IT 8.851890 0.267620 0.266599 0.000000 0.003064 \n", - "L6b 12.191126 0.372014 0.378840 0.000000 0.006826 \n", - "Lamp5 15.744548 0.353063 0.412253 0.000000 0.005192 \n", - "Micro-PVM 3.591667 0.004861 0.000694 0.000694 0.000000 \n", - "OPC 4.641860 0.046512 0.069767 0.000000 0.000000 \n", - "Oligo 5.538625 0.036980 0.047435 0.000000 0.001162 \n", - "Pvalb 18.290524 0.482544 0.540524 0.000623 0.019950 \n", - "Sncg 8.017094 0.222222 0.316239 0.000000 0.000000 \n", - "Sst 21.625330 0.508355 0.578716 0.000000 0.006157 \n", - "Sst Chodl 20.053572 0.642857 0.428571 0.000000 0.000000 \n", - "VLMC 2.623077 0.001923 0.001923 0.003846 0.051923 \n", - "Vip 10.467456 0.279290 0.257988 0.000000 0.002367 \n", - "\n", - " Sox17 Mrpl15 Lypla1 Tcea1 Rgs20 ... \\\n", - "subclass_Bakken_2022 ... \n", - "Astro 0.000688 0.051944 0.231854 0.255590 5.739250 ... \n", - "Endo 0.242340 0.030641 0.186630 0.286908 0.286908 ... \n", - "L2/3 IT 0.000000 0.124054 0.194718 0.380443 1.034119 ... \n", - "L5 ET 0.000000 0.132948 0.161850 0.297688 0.343931 ... \n", - "L5 IT 0.000000 0.096238 0.185658 0.354597 0.436538 ... \n", - "L5/6 NP 0.000000 0.084932 0.110959 0.379452 0.083562 ... \n", - "L6 CT 0.000000 0.114635 0.180879 0.398403 0.722340 ... \n", - "L6 IT 0.000000 0.091931 0.146067 0.371808 0.432074 ... \n", - "L6b 0.000000 0.122867 0.201365 0.426621 1.911263 ... \n", - "Lamp5 0.000000 0.102804 0.127726 0.414330 0.063344 ... \n", - "Micro-PVM 0.000000 0.039583 0.136111 0.232639 0.277431 ... \n", - "OPC 0.000000 0.083721 0.176744 0.311628 1.209302 ... \n", - "Oligo 0.000000 0.040465 0.129332 0.249177 0.124685 ... \n", - "Pvalb 0.001247 0.120948 0.289900 0.474439 0.115337 ... \n", - "Sncg 0.000000 0.119658 0.179487 0.461538 0.324786 ... \n", - "Sst 0.000000 0.093228 0.204925 0.401935 0.294635 ... \n", - "Sst Chodl 0.000000 0.071429 0.178571 0.535714 0.089286 ... \n", - "VLMC 0.005769 0.076923 0.230769 0.426923 0.296154 ... \n", - "Vip 0.000000 0.079290 0.140828 0.323077 0.125444 ... \n", - "\n", - " AC132444.5 Csprs Gm12406 Gm6313 Gm45121 \\\n", - "subclass_Bakken_2022 \n", - "Astro 0.00000 0.000000 0.001032 0.00000 0.000000 \n", - "Endo 0.00000 0.000000 0.000000 0.00000 0.000000 \n", - "L2/3 IT 0.00000 0.000000 0.000286 0.00000 0.000286 \n", - "L5 ET 0.00000 0.000000 0.000000 0.00000 0.000000 \n", - "L5 IT 0.00022 0.000000 0.000000 0.00011 0.000110 \n", - "L5/6 NP 0.00000 0.000000 0.000000 0.00000 0.000000 \n", - "L6 CT 0.00000 0.000235 0.000000 0.00000 0.000000 \n", - "L6 IT 0.00000 0.000000 0.000000 0.00000 0.000000 \n", - "L6b 0.00000 0.000000 0.000000 0.00000 0.000000 \n", - "Lamp5 0.00000 0.000000 0.000000 0.00000 0.000000 \n", - "Micro-PVM 0.00000 0.000000 0.000000 0.00000 0.000000 \n", - "OPC 0.00000 0.000000 0.000000 0.00000 0.000000 \n", - "Oligo 0.00000 0.000000 0.000000 0.00000 0.000000 \n", - "Pvalb 0.00000 0.000000 0.000000 0.00000 0.000000 \n", - "Sncg 0.00000 0.000000 0.000000 0.00000 0.000000 \n", - "Sst 0.00000 0.000000 0.000000 0.00000 0.000000 \n", - "Sst Chodl 0.00000 0.000000 0.000000 0.00000 0.000000 \n", - "VLMC 0.00000 0.000000 0.000000 0.00000 0.000000 \n", - "Vip 0.00000 0.000000 0.001183 0.00000 0.001183 \n", - "\n", - " Gm47020 Gm48133 Nhlrc4 Dsg1c Ercc6l \n", - "subclass_Bakken_2022 \n", - "Astro 0.000000 0.00000 0.000000 0.000000 0.000000 \n", - "Endo 0.000000 0.00000 0.000000 0.000000 0.000000 \n", - "L2/3 IT 0.000143 0.00000 0.000000 0.000000 0.000000 \n", - "L5 ET 0.000000 0.00000 0.000000 0.000000 0.000000 \n", - "L5 IT 0.000000 0.00011 0.000000 0.000000 0.000000 \n", - "L5/6 NP 0.000000 0.00000 0.000000 0.000000 0.000000 \n", - "L6 CT 0.000000 0.00047 0.000235 0.000470 0.000000 \n", - "L6 IT 0.000000 0.00000 0.000000 0.000000 0.001021 \n", - "L6b 0.000000 0.00000 0.000000 0.000000 0.000000 \n", - "Lamp5 0.000000 0.00000 0.000000 0.000000 0.000000 \n", - "Micro-PVM 0.000000 0.00000 0.000000 0.000000 0.000000 \n", - "OPC 0.000000 0.00000 0.000000 0.000000 0.000000 \n", - "Oligo 0.000000 0.00000 0.000000 0.000387 0.000194 \n", - "Pvalb 0.000000 0.00000 0.000000 0.000000 0.000000 \n", - "Sncg 0.000000 0.00000 0.000000 0.000000 0.000000 \n", - "Sst 0.000000 0.00000 0.000000 0.000000 0.000000 \n", - "Sst Chodl 0.000000 0.00000 0.000000 0.000000 0.000000 \n", - "VLMC 0.000000 0.00000 0.000000 0.000000 0.000000 \n", - "Vip 0.000000 0.00000 0.000000 0.000000 0.000000 \n", - "\n", - "[19 rows x 24275 columns]" + "" ] }, - "execution_count": 20, + "execution_count": 3, "metadata": {}, "output_type": "execute_result" + }, + { + "data": { + "image/png": "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REQkCyxSEBEREREREZEssEhBRERERERERLLAIgURERERERERyQKLFEREREREREQkCyxSEBEREREREZEssEhBRERERERERLIgmyLFtGnToFAoMGTIEKmjEBEREREREZEEZFGkOHnyJJYuXQoXFxepoxARERERERGRRCQvUrx8+RJdunTBH3/8gWLFikkdh4iIiIiIiIgkoit1gP79+6NFixZo3LgxpkyZku26ycnJSE5OVl1PTEz83PGIiD7KYdRuqSNkKWZ6C6kjEBERERHlmKRFio0bN+LMmTM4efJkjtafNm0aJk6c+JlTEREREREREZEUJCtSxMXFYfDgwdi7dy8MDQ1zdJvRo0dj6NChquuJiYmws7P7XBGJiIgKDHvkEBEREUlYpDh9+jQePnyIOnXqqNrS0tJw8OBBzJ8/H8nJydDR0VG7jYGBAQwMDAo6KhEREREREREVAMmKFF5eXrhw4YJaW8+ePeHo6IiRI0dqFCiIiIiIiIiIqHCTrEhhZmYGZ2dntTYTExNYWVlptBMRERERERFR4Sf5FKRERERERERERIAMpiB934EDB6SOQEREREREREQSYU8KIiIiIiIiIpIFFimIiIiIiIiISBZYpCAiIiIiIiIiWWCRgoiIiIiIiIhkgUUKIiIiIiIiIpIFFimIiIiIiIiISBZYpCAiIiIiIiIiWWCRgoiIiIiIiIhkgUUKIiIiIiIiIpIFFimIiIiIiIiISBZYpCAiIiIiIiIiWWCRgoiIiIiIiIhkgUUKIiIiIiIiIpIF3U+58du3b/Hw4UOkp6ertZcrV+6TQhERERERERFR0ZOnIkV0dDT8/f1x9OhRtXYhBBQKBdLS0vIlHBEREREREREVHXkqUvTo0QO6urrYtWsXSpcuDYVCkd+5iIiIiIiIiKiIyVOR4ty5czh9+jQcHR3zOw8RERERERERFVF5KlJUrVoVjx8/zu8sREREeeIwarfUEbIUM72F1BGIiIiItEaeZveYMWMGRowYgQMHDuDJkydITExUuxARERERERER5VaeelI0btwYAODl5aXWzoEziQoWjx4TEREREVFhkqciRURERH7nICIiIiIiIqIiLk9FCg8Pj3x58EWLFmHRokWIiYkBAFSrVg3jx49Hs2bN8uX+iYiIiIiIiEh75KlIAQDPnj3D8uXLceXKFSgUClStWhX+/v6w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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" } ], "source": [ - "mean_expression_df" + "%matplotlib inline\n", + "import matplotlib.pyplot as plt\n", + "plt.figure(figsize=(13,2))\n", + "plt.xticks(rotation=90)\n", + "plt.ylabel('Expression')\n", + "plt.title('Epha7 expression for mouse motor cortex cell types')\n", + "plt.bar(mean_expression_df.index,mean_expression_df['Epha7'].values)" ] }, { diff --git a/docs/tutorials/model_training_and_eval.ipynb b/docs/tutorials/model_training_and_eval.ipynb index e7ab2c9..0af711e 100644 --- a/docs/tutorials/model_training_and_eval.ipynb +++ b/docs/tutorials/model_training_and_eval.ipynb @@ -26,7 +26,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -46,20 +46,9 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "2024-10-09 14:34:29.606108: I tensorflow/core/util/port.cc:113] oneDNN custom operations are on. You may see slightly different numerical results due to floating-point round-off errors from different computation orders. To turn them off, set the environment variable `TF_ENABLE_ONEDNN_OPTS=0`.\n", - "2024-10-09 14:34:29.645116: I tensorflow/core/platform/cpu_feature_guard.cc:210] This TensorFlow binary is optimized to use available CPU instructions in performance-critical operations.\n", - "To enable the following instructions: AVX2 AVX512F AVX512_VNNI AVX512_BF16 AVX512_FP16 AVX_VNNI AMX_TILE AMX_INT8 AMX_BF16 FMA, in other operations, rebuild TensorFlow with the appropriate compiler flags.\n", - "2024-10-09 14:34:32.865724: W tensorflow/compiler/tf2tensorrt/utils/py_utils.cc:38] TF-TRT Warning: Could not find TensorRT\n" - ] - } - ], + "outputs": [], "source": [ "import crested" ] @@ -986,9 +975,20 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 1, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2024-11-02 16:58:46.208674: I tensorflow/core/util/port.cc:113] oneDNN custom operations are on. You may see slightly different numerical results due to floating-point round-off errors from different computation orders. To turn them off, set the environment variable `TF_ENABLE_ONEDNN_OPTS=0`.\n", + "2024-11-02 16:58:46.244576: I tensorflow/core/platform/cpu_feature_guard.cc:210] This TensorFlow binary is optimized to use available CPU instructions in performance-critical operations.\n", + "To enable the following instructions: AVX2 AVX512F AVX512_VNNI AVX512_BF16 AVX512_FP16 AVX_VNNI AMX_TILE AMX_INT8 AMX_BF16 FMA, in other operations, rebuild TensorFlow with the appropriate compiler flags.\n", + "2024-11-02 16:58:49.297018: W tensorflow/compiler/tf2tensorrt/utils/py_utils.cc:38] TF-TRT Warning: Could not find TensorRT\n" + ] + } + ], "source": [ "import anndata\n", "import crested\n", @@ -1005,9 +1005,17 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 2, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2024-11-02 16:58:59.383660: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1928] Created device /job:localhost/replica:0/task:0/device:GPU:0 with 78790 MB memory: -> device: 0, name: NVIDIA H100 80GB HBM3, pci bus id: 0000:d2:00.0, compute capability: 9.0\n" + ] + } + ], "source": [ "# load an existing model\n", "evaluator = crested.tl.Crested(data=datamodule)\n", @@ -1424,9 +1432,22 @@ }, { "cell_type": "code", - "execution_count": 30, + "execution_count": 3, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "WARNING: All log messages before absl::InitializeLog() is called are written to STDERR\n", + "I0000 00:00:1730563148.517470 3344699 service.cc:145] XLA service 0x7f8db801dd90 initialized for platform CUDA (this does not guarantee that XLA will be used). Devices:\n", + "I0000 00:00:1730563148.517510 3344699 service.cc:153] StreamExecutor device (0): NVIDIA H100 80GB HBM3, Compute Capability 9.0\n", + "2024-11-02 16:59:08.533549: I tensorflow/compiler/mlir/tensorflow/utils/dump_mlir_util.cc:268] disabling MLIR crash reproducer, set env var `MLIR_CRASH_REPRODUCER_DIRECTORY` to enable.\n", + "2024-11-02 16:59:08.614439: I external/local_xla/xla/stream_executor/cuda/cuda_dnn.cc:465] Loaded cuDNN version 8907\n", + "I0000 00:00:1730563150.764167 3344699 device_compiler.h:188] Compiled cluster using XLA! This line is logged at most once for the lifetime of the process.\n" + ] + } + ], "source": [ "chrom = \"chr4\"\n", "start = 91209533\n", @@ -1446,7 +1467,7 @@ }, { "cell_type": "code", - "execution_count": 31, + "execution_count": 4, "metadata": {}, "outputs": [], "source": [ @@ -1456,7 +1477,7 @@ }, { "cell_type": "code", - "execution_count": 32, + "execution_count": 5, "metadata": {}, "outputs": [ { @@ -1471,6 +1492,7 @@ } ], "source": [ + "%matplotlib inline\n", "crested.pl.hist.locus_scoring(\n", " scores,\n", " (min_loc, max_loc),\n", diff --git a/src/crested/tl/_crested.py b/src/crested/tl/_crested.py index 66539ed..853a7ce 100644 --- a/src/crested/tl/_crested.py +++ b/src/crested/tl/_crested.py @@ -718,6 +718,7 @@ def score_gene_locus( window_size: int = 2114, central_size: int = 1000, step_size: int = 50, + genome: FastaFile | None = None, ) -> tuple[np.ndarray, np.ndarray, int, int, int]: """ Score regions upstream and downstream of a gene locus using the model's prediction. @@ -746,6 +747,8 @@ def score_gene_locus( Size of the central region that the model predicts for. Default 1000. step_size Distance between consecutive windows. Default 50. + genome + Genome of species to score locus on. If none, genome of crested class is used. Returns ------- @@ -784,7 +787,8 @@ def score_gene_locus( all_class_names = list(self.anndatamodule.adata.obs_names) idx = all_class_names.index(class_name) - genome = FastaFile(self.anndatamodule.genome_file) + if genome is None: + genome = FastaFile(self.anndatamodule.genome_file) # Generate all windows and one-hot encode the sequences in parallel all_sequences = []