{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Random Forests Are Worse At Predicting Certain Samples and Targets In Conditioned Datasets"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "import scanpy as sc\n",
    "\n",
    "import pickle \n",
    "\n",
    "data_location = \"../data/aging_brain/\"\n",
    "\n",
    "young = pickle.load(open(data_location + \"aging_brain_young.pickle\",mode='rb'))\n",
    "old = pickle.load(open(data_location + \"aging_brain_old.pickle\",mode='rb'))\n",
    "\n",
    "filtered = pickle.load(open(data_location + \"aging_brain_filtered.pickle\",mode='rb'))\n",
    "\n",
    "batch_encoding = np.loadtxt(data_location + 'aging_batch_encoding.tsv')\n",
    "batch_encoding = batch_encoding.astype(dtype=bool)\n",
    "\n",
    "young_mask = np.zeros(37069,dtype=bool)\n",
    "old_mask = np.zeros(37069,dtype=bool)\n",
    "\n",
    "young_mask[:young.shape[0]] = True\n",
    "old_mask[young.shape[0]:] = True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# sc.pp.neighbors(filtered)\n",
    "# sc.tl.umap(filtered)\n",
    "# sc.tl.louvain(filtered)\n",
    "# sc.pl.umap(filtered,color='louvain')\n",
    "!ls {data_location}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "import scanpy as sc\n",
    "\n",
    "import sys\n",
    "# sys.path.append('/localscratch/bbrener1/rusty_forest_v3/src')\n",
    "sys.path.append('../')\n",
    "sys.path.append('../rusty_axe/')\n",
    "import tree_reader as tr \n",
    "import lumberjack\n",
    "\n",
    "data_location = \"../data/aging_brain/\"\n",
    "\n",
    "# forest = tr.Forest.load(data_location + 'scanpy_cmp_aging_brain_true_l1')\n",
    "# forest = tr.Forest.load(data_location + 'full_clustering_predicted')\n",
    "forest = tr.Forest.load(data_location + \"cv_forest_trimmed_extra\")\n",
    "forest.arguments\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "feature_mask = np.zeros(young.X.shape[1],dtype=bool)\n",
    "for feature in forest.output_features:\n",
    "    fi = list(young.var_names).index(feature)\n",
    "    feature_mask[fi] = True\n",
    "    \n",
    "young = young[:,feature_mask]\n",
    "old = old[:,feature_mask]\n",
    "\n",
    "print(young.shape)\n",
    "print(old.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "forest.html_tree_summary(n=5)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "forest.tsne_coordinates = filtered.obsm[\"X_umap\"][young_mask]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "forest.old_predictions = forest.predict(old.X)\n",
    "forest.young_predictions = forest.predict(young.X)\n",
    "forest.young_predictions.node_sample_encoding()\n",
    "forest.old_predictions.node_sample_encoding()\n",
    "\n",
    "young_residuals = forest.young_predictions.residuals()\n",
    "old_residuals = forest.old_predictions.residuals()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "forest.backup(data_location + \"full_clustering_predicted\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "forest.young_predictions.prediction_report()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "null_young_residuals = np.power(young.X - np.mean(young.X,axis=0),2)\n",
    "null_old_residuals = np.power(old.X - np.mean(old.X,axis=0),2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "young_sample_absolute_residuals = np.sum(np.abs(young_residuals),axis=1)\n",
    "young_sample_square_residuals = np.sum(np.power(young_residuals,2),axis=1)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# plt.figure()\n",
    "# plt.scatter(*filtered.obsm['X_umap'][young_mask].T,c=young_sample_absolute_residuals,s=3)\n",
    "# plt.colorbar()\n",
    "# plt.show()\n",
    "\n",
    "plt.figure()\n",
    "plt.scatter(*filtered.obsm['X_umap'][young_mask].T,c=young_sample_square_residuals,s=3)\n",
    "plt.colorbar()\n",
    "plt.show()\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "old_sample_absolute_residuals = np.sum(np.abs(old_residuals),axis=1)\n",
    "old_sample_square_residuals = np.sum(np.power(old_residuals,2),axis=1)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# plt.figure()\n",
    "# plt.scatter(*filtered.obsm['X_umap'][old_mask].T,c=old_sample_absolute_residuals,s=3)\n",
    "# plt.colorbar()\n",
    "# plt.show()\n",
    "\n",
    "plt.figure()\n",
    "plt.scatter(*filtered.obsm['X_umap'][old_mask].T,c=old_sample_square_residuals,s=3)\n",
    "plt.colorbar()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# plt.figure()\n",
    "# plt.scatter(young_sample_absolute_residuals,young_sample_young_node_residuals,s=1)\n",
    "# plt.show()\n",
    "\n",
    "# plt.figure()\n",
    "# plt.scatter(old_sample_absolute_residuals,old_sample_young_node_residuals,s=1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# plt.figure()\n",
    "# plt.scatter(node_young_mean_residuals,node_old_mean_residuals,s=1)\n",
    "# plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# young_nsr2 = forest.young_predictions.node_sample_r2()\n",
    "# forest.old_predictions.nsr2 = None\n",
    "# old_nsr2 = forest.old_predictions.node_sample_r2()\n",
    "\n",
    "# young_node_size = np.sum(forest.young_predictions.node_sample_encoding(),axis=1)\n",
    "# old_node_size = np.sum(forest.old_predictions.node_sample_encoding(),axis=1)\n",
    "\n",
    "# young_node_mean_r2 = np.sum(young_nsr2,axis=1) / young_node_size\n",
    "# old_node_mean_r2 = np.sum(old_nsr2,axis=1) / old_node_size\n",
    "\n",
    "# plt.figure()\n",
    "# plt.scatter(young_node_mean_r2[leaf_mask],old_node_mean_r2[leaf_mask],s=1)\n",
    "# plt.show()\n",
    "\n",
    "# old_node_mean_r2[leaf_mask]\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": false
   },
   "outputs": [],
   "source": [
    "# young_sample_young_node_residuals = []    \n",
    "# old_sample_young_node_residuals = []\n",
    "\n",
    "# for i,old_sample_encoding in enumerate(forest.old_predictions.node_sample_encoding()[leaf_mask].T):\n",
    "#     if i % 100 == 0:\n",
    "#         print(i)\n",
    "#     mean_young_node_residuals = np.mean(young_node_mean_r2[leaf_mask][old_sample_encoding])\n",
    "#     mean_old_node_residuals = np.mean(old_node_mean_r2[leaf_mask][old_sample_encoding])\n",
    "#     young_sample_young_node_residuals.append(mean_young_node_residuals)\n",
    "#     old_sample_young_node_residuals.append(mean_old_node_residuals)\n",
    "\n",
    "\n",
    "# plt.figure()\n",
    "# plt.scatter(young_sample_young_node_residuals,old_sample_young_node_residuals,s=1)\n",
    "# plt.plot([0,700],[0,700],color='red')\n",
    "# plt.show()\n",
    "\n",
    "# plt.figure()\n",
    "# plt.scatter(young_sample_absolute_residuals,young_sample_young_node_residuals,s=1)\n",
    "# plt.show()\n",
    "\n",
    "# plt.figure()\n",
    "# plt.scatter(old_sample_absolute_residuals,old_sample_young_node_residuals,s=1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "node_residual_delta = np.array(old_sample_young_node_residuals) - np.array(young_sample_young_node_residuals)\n",
    "\n",
    "plt.figure()\n",
    "plt.title(\"Largest Changes In Node Residuals\")\n",
    "plt.scatter(*filtered.obsm[\"X_umap\"][old_mask].T,cmap='viridis',c=node_residual_delta,s=1)\n",
    "plt.colorbar(label=\"Increase in Node R2\")\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Of course we can't make entirely direct comparisons on the prediction error for samples, because we can never be certain to what degree the sample matching procedure would bias our result. (In a fundamental sense, when we attempt to match samples to each other, we will do so on the basis of their residuals relative to whatever model or error function we pick)\n",
    "\n",
    "But we can make meaningful comparisons of the degree of mismatch for both features and node clusters:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "young_feature_fvu = forest.young_predicitons.feature_remaining_error(mode='mean')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": false
   },
   "outputs": [],
   "source": [
    "# First let's get a sense for the kinds of FVU values we can observe \n",
    "\n",
    "plt.figure()\n",
    "plt.title(\"Null Feature FVUs (Lower Is Better)\")\n",
    "plt.hist(young_feature_fvu,bins=100)\n",
    "plt.xlabel(\"FVU\")\n",
    "plt.ylabel(\"Frequency\")\n",
    "plt.show()\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Now let's examine the quality of predictions for features in the old \n",
    "# Cells\n",
    "\n",
    "old_feature_fvu = forest.old_predictions.feature_remaining_error(mode='mean')\n",
    "\n",
    "# Note something interesting:\n",
    "\n",
    "print(np.sum(old_feature_fvu > 1.))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "\n",
    "masked_fvu = old_feature_fvu.copy()\n",
    "masked_fvu[old_feature_fvu > 1] = 1\n",
    "\n",
    "plt.figure()\n",
    "plt.title(\"Predicted Feature FVUs (Lower Is Better)\")\n",
    "plt.hist(masked_fvu,bins=100)\n",
    "plt.xlabel(\"FVU\")\n",
    "plt.ylabel(\"Frequency\")\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now we see one of the difficulties in using Fraction of Variance Left Unexplained as a comparison metric. When a new dataset is introduced to a regressor, the value can suddenly fall outside the 0-1 range. Even more troublesome: for certain genes, notably ones not expressed in the young cells, we can even experience divisions by zero. As a correlary, the Coefficient of Determination can even become negative, and thus is also challenging to use.\n",
    "\n",
    "But of course, we are also interested in the features for which the FVU changes most substantially. After all, there are plenty of poorly predictable features even in our original dataset. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "delta_fvu = old_feature_fvu - young_feature_fvu\n",
    "\n",
    "delta_fvu_sort = np.argsort(np.abs(delta_fvu))\n",
    "\n",
    "plt.figure()\n",
    "plt.hist(delta_fvu[delta_fvu < 1],bins=100)\n",
    "plt.show()\n",
    "\n",
    "# Let's take a look at the top 20 ranked features by the difference in\n",
    "# prediction quality \n",
    "\n",
    "print(forest.output_features[delta_fvu_sort[-20:]])\n",
    "print(delta_fvu[delta_fvu_sort[-20:]])\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# At face value we may immediately observe that Gh (growth hormone) is an\n",
    "# extremely classic gene affected by aging, as is Ave (Vassopressin), \n",
    "# Chorionic Gonadotropin (monomer of FSH,LH, and TSH to boot),\n",
    "\n",
    "# More interestingly, their behavior is easily detectable as different \n",
    "# through the use of a random forest, but for example Lyve1 and Clec4d \n",
    "# appear to have completely insignificant differential expression, and Avp is quite \n",
    "# low-ranked. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": false
   },
   "outputs": [],
   "source": [
    "gene = \"Klk6\"\n",
    "gene_index = forest.truth_dictionary.feature_dictionary[gene]\n",
    "\n",
    "# plt.figure()\n",
    "# plt.hist(young.X[:,gene_index],bins=100,log=True)\n",
    "# plt.show()\n",
    "\n",
    "# plt.figure()\n",
    "# plt.hist(old.X[:,gene_index],bins=100,log=True)\n",
    "# plt.show()\n",
    "\n",
    "plt.figure()\n",
    "plt.scatter(*filtered.obsm['X_umap'][young_mask].T,c=young.X[:,gene_index],s=3)\n",
    "plt.show()\n",
    "plt.figure()\n",
    "plt.scatter(*filtered.obsm['X_umap'][old_mask].T,c=old.X[:,gene_index],s=3)\n",
    "plt.show()\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Factor Discrepancies "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "\n",
    "comparisons = forest.young_predictions.compare_factors(forest.old_predictions,bins=100)\n",
    "\n",
    "print(comparisons)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": false
   },
   "outputs": [],
   "source": [
    "clust_intr = 7\n",
    "clust = forest.split_clusters[clust_intr]\n",
    "\n",
    "# Let's sort features by young COD and Mean Delta\n",
    "\n",
    "young_error,young_error_parent = forest.young_predictions.factor_feature_error(clust)\n",
    "old_error,old_error_parent = forest.old_predictions.factor_feature_error(clust)\n",
    "\n",
    "young_cod = 1 - (young_error+1)/(young_error_parent+1)\n",
    "old_cod = 1 - (old_error+1)/(old_error_parent+1)\n",
    "\n",
    "mean_delta = np.mean(forest.node_representation(clust.nodes,mode='additive_mean'),axis=0)\n",
    "\n",
    "delta_sort = np.argsort(mean_delta)\n",
    "cod_sort = np.argsort(young_cod)\n",
    "\n",
    "print(young_cod[cod_sort[:20]])\n",
    "print(young_cod[cod_sort[-20:]])\n",
    "print(young_cod[delta_sort[20:]])\n",
    "print(young_cod[delta_sort[-20:]])\n",
    "\n",
    "# Now let's select the cells of interest to us (predicted to be common in cluster of interest)\n",
    "\n",
    "young_scores = forest.young_predictions.factor_matrix()[:,clust_intr]\n",
    "old_scores = forest.old_predictions.factor_matrix()[:,clust_intr]\n",
    "\n",
    "plt.figure()\n",
    "plt.hist(young_scores,bins=40,log=True)\n",
    "plt.show()\n",
    "\n",
    "plt.figure()\n",
    "plt.hist(old_scores,bins=40,log=True)\n",
    "plt.show()\n",
    "\n",
    "# Visually ID a cutoff \n",
    "\n",
    "young_factor_mask = np.abs(young_scores) > .025\n",
    "old_factor_mask = np.abs(old_scores) > .025\n",
    "# young_factor_mask = young_scores > .025\n",
    "# old_factor_mask = old_scores > .025\n",
    "\n",
    "\n",
    "# Select the cells from each dataset and plot an agglomerated heatmap\n",
    "\n",
    "young_factor_sort = np.argsort(young_scores[young_factor_mask])\n",
    "old_factor_sort = np.argsort(old_scores[old_factor_mask])\n",
    "\n",
    "young_selection = young.X[young_factor_mask][young_factor_sort[::-1]]\n",
    "old_selection = old.X[old_factor_mask][old_factor_sort[::-1]]\n",
    "\n",
    "# relevant_features = cod_sort[-200:]\n",
    "relevant_features = delta_sort[-200:]\n",
    "\n",
    "from scipy.cluster.hierarchy import linkage,dendrogram\n",
    "\n",
    "feature_agg = dendrogram(linkage(young_selection.T[relevant_features], method='average'), no_plot=True)['leaves']\n",
    "\n",
    "relevant_young = young_selection.T[relevant_features][feature_agg].T\n",
    "relevant_old = old_selection.T[relevant_features][feature_agg].T\n",
    "\n",
    "plt.figure(figsize=(4,3))\n",
    "plt.title(f\"Top 200 Most Determined Genes, Cluster {clust.name()}\\n Young Cells\")\n",
    "plt.imshow(relevant_young,aspect='auto',interpolation='none')\n",
    "plt.xlabel(\"Genes\")\n",
    "plt.ylabel(\"Cells\")\n",
    "plt.colorbar(label=\"Expression (Log TPM)\")\n",
    "plt.show()\n",
    "\n",
    "plt.figure(figsize=(4,3))\n",
    "plt.title(f\"Top 200 Most Determined Genes, Cluster {clust.name()}\\n Old Cells\")\n",
    "plt.imshow(relevant_old,aspect='auto',interpolation='none')\n",
    "plt.xlabel(\"Genes\")\n",
    "plt.ylabel(\"Cells\")\n",
    "plt.colorbar(label=\"Expression (Log TPM)\")\n",
    "plt.show()\n",
    "\n",
    "young_sample_agg = dendrogram(linkage(young_selection, method='average'), no_plot=True)['leaves']\n",
    "old_sample_agg = dendrogram(linkage(old_selection, method='average'), no_plot=True)['leaves']\n",
    "\n",
    "plt.figure(figsize=(4,3))\n",
    "plt.title(f\"Top 200 Most Determined Genes, Cluster {clust.name()}\\n Young Cells\")\n",
    "plt.imshow(young_selection[young_sample_agg].T[relevant_features][feature_agg].T,aspect='auto',interpolation='none')\n",
    "plt.xlabel(\"Genes\")\n",
    "plt.ylabel(\"Cells\")\n",
    "plt.colorbar(label=\"Expression (Log TPM)\")\n",
    "plt.show()\n",
    "\n",
    "plt.figure(figsize=(4,3))\n",
    "plt.title(f\"Top 200 Most Determined Genes, Cluster {clust.name()}\\n Young Cells\")\n",
    "plt.imshow(old_selection[old_sample_agg].T[relevant_features][feature_agg].T,aspect='auto',interpolation='none')\n",
    "plt.xlabel(\"Genes\")\n",
    "plt.ylabel(\"Cells\")\n",
    "plt.colorbar(label=\"Expression (Log TPM)\")\n",
    "plt.show()\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "plt.figure()\n",
    "plt.imshow(young_scores[young_factor_mask][young_factor_sort[::-1]].reshape([-1,1]),aspect='auto',cmap='bwr',vmin=-.25,vmax=.25)\n",
    "plt.colorbar()\n",
    "plt.show()\n",
    "\n",
    "plt.figure()\n",
    "plt.imshow(old_scores[old_factor_mask][old_factor_sort[::-1]].reshape([-1,1]),aspect='auto',cmap='bwr',vmin=-.25,vmax=.25)\n",
    "plt.colorbar()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# forest.young_predicitons.nse[0].shape\n",
    "# selection = forest.young_predicitons.matrix[forest.young_predicitons.nse[0]]\n",
    "# forest.young_predicitons.nsr2 = None\n",
    "# forest.old_predictions.nsr2 = None\n",
    "# np.sum(forest.young_predicitons.node_sample_r2(),axis=1)[12]\n",
    "# young_fvus = []\n",
    "# old_fvus = []\n",
    "# for factor in forest.split_clusters:\n",
    "#     y_f,o_f = forest.young_predictions.compare_factor_fvu(forest.old_predictions,factor)\n",
    "#     young_fvus.append(y_f)\n",
    "#     old_fvus.append(o_f)\n",
    "fractions = []\n",
    "for factor in forest.split_clusters[1:]:\n",
    "    young_fractions = np.mean([forest.young_predictions.node_fraction(n) for n in factor.nodes])\n",
    "    old_fractions = np.mean([forest.old_predictions.node_fraction(n) for n in factor.nodes])\n",
    "    fractions.append((young_fractions,old_fractions))\n",
    "    \n",
    "print(list(enumerate(fractions)))\n",
    "    \n",
    "    # for factor in forest.split_clusters[1:]:\n",
    "#     fractions.append(forest.young_predictions.compare_factor_fractions(forest.old_predictions,factor))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "cluster = forest.split_clusters[7]\n",
    "\n",
    "young_error = forest.young_predictions.factor_feature_error(cluster)\n",
    "old_error = forest.old_predictions.factor_feature_error(cluster)\n",
    "\n",
    "young_cod = 1 - ((young_error[0]+1)/(young_error[1]+1))\n",
    "old_cod = 1 - ((old_error[0]+1)/(old_error[1]+1))\n",
    "\n",
    "delta = young_cod - old_cod\n",
    "\n",
    "delta_sort = np.argsort(delta)\n",
    "young_sort = np.argsort(young_cod)\n",
    "\n",
    "print(forest.output_features[young_sort[-20:]])\n",
    "print(young_cod[young_sort[-20:]])\n",
    "print(old_cod[young_sort[-20:]])\n",
    "# print(forest.output_features[delta_sort[-20:]])\n",
    "# print(young_cod[delta_sort[-20:]])\n",
    "# print(old_cod[delta_sort[-20:]])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "young_cods = np.ones(len(young_fvus)) - young_fvus\n",
    "old_cods = np.ones(len(old_fvus)) - old_fvus\n",
    "delta = young_cods - old_cods\n",
    "ratio = delta/young_cods\n",
    "\n",
    "print(list(enumerate(zip(young_cods,old_cods))))\n",
    "print(list(enumerate(ratio)))\n",
    "plt.figure()\n",
    "plt.scatter(young_cods,old_cods)\n",
    "plt.plot([0,.35],[0,.35])\n",
    "# plt.scatter(np.arange(len(delta)),delta)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "\n",
    "# plt.figure()\n",
    "# plt.title(f'Umap Embedding, Mouse Brain')\n",
    "# plt.scatter(*young.obsm['X_umap'].T,c=forest.sample_labels,cmap='rainbow',s=1,alpha=1)\n",
    "# plt.show()\n",
    "\n",
    "# plt.figure()\n",
    "# plt.title(f'Repredicted Embedding, Young Mouse Brain')\n",
    "# plt.scatter(*young_repredicted[:,-2:].T,s=1,alpha=1)\n",
    "# plt.show()\n",
    "\n",
    "\n",
    "# plt.figure()\n",
    "# plt.title(f'Repredicted Embedding, Aged Mouse Brain')\n",
    "# plt.scatter(*old_repredicted[:,-2:].T,s=1,alpha=1)\n",
    "# plt.show()\n",
    "\n",
    "\n",
    "# feature = \"Retnlg\"\n",
    "# f_i = forest.truth_dictionary.feature_dictionary[feature]\n",
    "# plt.figure()\n",
    "# plt.title(f'{feature}')\n",
    "# plt.scatter(*filtered.obsm['X_umap'][young_mask].T,c=filtered.X[:,f_i][young_mask],s=3,alpha=.4)\n",
    "# plt.show()\n",
    "\n",
    "# plt.figure()\n",
    "# plt.title(f'{feature}')\n",
    "# plt.scatter(*filtered.obsm['X_umap'][old_mask].T,c=filtered.X[:,f_i][old_mask],s=3,alpha=.4)\n",
    "# plt.show()\n",
    "\n",
    "# print(young_cod[f_i])\n",
    "# print(old_cod[f_i])\n",
    "\n",
    "# feature = \"Fyn\"\n",
    "# f_i = forest.truth_dictionary.feature_dictionary[feature]\n",
    "\n",
    "# plt.figure()\n",
    "# plt.title(f'Repredicted Embedding, Young Mouse Brain')\n",
    "# plt.scatter(*young_repredicted[:,-2:].T,c=young.X[:,f_i],s=1,alpha=1)\n",
    "# plt.show()\n",
    "\n",
    "\n",
    "# plt.figure()\n",
    "# plt.title(f'Repredicted Embedding, Aged Mouse Brain')\n",
    "# plt.scatter(*old_repredicted[:,-2:].T,c=old.X[:,f_i],s=1,alpha=1)\n",
    "# plt.show()\n",
    "\n",
    "\n",
    "feature = \"Tmem119\"\n",
    "f_i = forest.truth_dictionary.feature_dictionary[feature]\n",
    "plt.figure()\n",
    "plt.title(f'{feature}')\n",
    "plt.scatter(*forest.tsne_coordinates.T,c=forest.output[:,f_i],s=3,alpha=.4)\n",
    "plt.colorbar()\n",
    "plt.show()\n",
    "\n",
    "feature = \"Cd74\"\n",
    "f_i = forest.truth_dictionary.feature_dictionary[feature]\n",
    "plt.figure()\n",
    "plt.title(f'{feature}')\n",
    "plt.scatter(*forest.tsne_coordinates.T,c=forest.output[:,f_i],s=3,alpha=.4)\n",
    "plt.colorbar()\n",
    "plt.show()\n",
    "\n",
    "\n",
    "# Immune cells: CD45/C1qc \n",
    "# Oligodendrocytes: Pdgfra/Sox10\n",
    "# Astrocytes: Aldoc/Cldn10\n",
    "# mature neurons/neuroendocrine: Syt1/Snap25\n",
    "# Ependymal cells: Rarres2/Dynlrb2\n",
    "# Vascular cells: Cldn5/Esam"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Predicting a tsne\n",
    "# forest.add_output_feature(forest.tsne_coordinates.T[0],\"tsne_0\")\n",
    "# forest.add_output_feature(forest.tsne_coordinates.T[1],\"tsne_1\")\n",
    "\n",
    "# forest.output_features.shape\n",
    "# forest.young_predictions.nme = None\n",
    "# forest.young_predictions.node_mean_encoding()\n",
    "\n",
    "# forest.old_predictions.nme = None\n",
    "# forest.old_predictions.node_mean_encoding()\n",
    "\n",
    "\n",
    "# young_repredicted = forest.young_predictions.prediction(mode=\"mean\")\n",
    "# old_repredicted = forest.old_predictions.prediction(mode=\"mean\")\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# distance = np.sqrt(np.sum(np.power(forest.tsne_coordinates - young_repredicted[:,-2:],2),axis=1))\n",
    "\n",
    "# plt.figure()\n",
    "# plt.hist(distance,bins=100)\n",
    "# plt.show()\n",
    "\n",
    "# plt.figure()\n",
    "# plt.scatter(forest.tsne_coordinates.T[0],young_repredicted[:,-2])\n",
    "# plt.show()\n",
    "\n",
    "# plt.figure()\n",
    "# plt.scatter(forest.tsne_coordinates.T[1],young_repredicted[:,-1])\n",
    "# plt.show()\n",
    "\n",
    "# np.sum((distance > 2).astype(dtype=int))\n",
    "\n",
    "# plt.figure()\n",
    "# plt.hist(forest.tsne_coordinates.T[0] - young_repredicted[:,-2],bins=100,log=True)\n",
    "# plt.show()\n",
    "\n",
    "# plt.figure()\n",
    "# plt.hist(forest.tsne_coordinates.T[1] - young_repredicted[:,-1],bins=100,log=True)\n",
    "# plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "plt.figure()\n",
    "plt.title(\"Changes in Factor Prediction Quality\")\n",
    "plt.scatter(comparisons[\"FVU Deltas\"],-np.log10(comparisons[\"P values\"]))\n",
    "plt.xlabel(\"Magnitude (Change In FVU)\")\n",
    "plt.ylabel(\"Significance, Change in MSE, -Log10(P Value)\")\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "forest.tsne_coordinates = filtered.obsm['X_umap'][young_mask]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# We need to look at the tree of these factors to really get a sense for what's going on\n",
    "# forest.likely_tree\n",
    "\n",
    "forest.html_tree_summary(n=10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "filtered.obsm['X_umap']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "sizes = np.array([len(n.samples()) for n in forest.split_clusters[17].nodes])\n",
    "sister_sizes = np.array([len(n.sister().samples()) for n in forest.split_clusters[17].nodes])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": false
   },
   "outputs": [],
   "source": [
    "plt.figure()\n",
    "plt.hist(sizes,bins=100)\n",
    "plt.show()\n",
    "\n",
    "plt.figure()\n",
    "plt.hist(sister_sizes,bins=100)\n",
    "plt.show()\n",
    "\n",
    "plt.figure()\n",
    "plt.hist(sizes-sister_sizes,bins=100)\n",
    "plt.show()\n",
    "\n",
    "plt.figure()\n",
    "plt.hist(sizes/sister_sizes,bins=100)\n",
    "plt.show()\n",
    "\n",
    "plt.figure()\n",
    "plt.hist(np.log(sizes/sister_sizes),bins=100)\n",
    "plt.show()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "for factor in reversed(forest.split_clusters[1:]): \n",
    "    print(factor.name())\n",
    "    young_self,young_parent = forest.young_predicitons.factor_total_error(factor)\n",
    "    young_fvu = np.sum(young_self)/ np.sum(young_parent)\n",
    "    print(f\"Young FVU: {young_fvu}\")\n",
    "    print(f\"Young COD: {1-young_fvu}\")\n",
    "    old_self,old_parent = forest.old_predictions.factor_total_error(factor)\n",
    "    old_fvu = np.sum(old_self)  / np.sum(old_parent)\n",
    "    print(f\"Old FVU: {old_fvu}\")\n",
    "    print(f\"Old COD: {1-old_fvu}\")b\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "self_error,parent_error = forest.split_clusters[17].raw_error()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "for factor in reversed(forest.split_clusters[1:]): \n",
    "    forest.young_predictions.compare_factor_means(forest.old_predictions,factor,plot=['distance','mean','scatter','rank'])\n",
    "    \n",
    "    \n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from scipy.stats import mannwhitneyu\n",
    "\n",
    "young_17_error = forest.young_predictions.factor_total_error(forest.split_clusters[17])\n",
    "old_17_error = forest.old_predictions.factor_total_error(forest.split_clusters[17])\n",
    "\n",
    "young_mse = np.sum(young_17_error[0]) / (np.sum([len(n.samples()) for n in forest.split_clusters[17].nodes]) * 2000)\n",
    "old_mse = np.sum(old_17_error[0]) / (np.sum([len(n.samples()) for n in forest.split_clusters[17].nodes]) * 2000)\n",
    "\n",
    "within_error = np.sum(young_17_error[0]) + np.sum(old_17_error[0])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print(young_mse)\n",
    "print(old_mse)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "ratio = self_error / parent_error"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "plt.figure()\n",
    "plt.hist(self_error,log=True)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "trick_sorted,trick_ratio = forest.split_clusters[17].error_ratio()\n",
    "\n",
    "plt.figure()\n",
    "plt.hist(trick_ratio,bins=100,log=True)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "forest.young_predicitons"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "forest.young"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "forest.young_predictions"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "factor = forest.split_clusters[16]\n",
    "\n",
    "young_self, young_parent = forest.young_predicitons.factor_total_error(factor)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "old_self,old_parent = forest.old_predictions.factor_total_error(factor)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "young_fvu = (young_self+1)/(young_parent+1)\n",
    "young_fvu[~np.isfinite(young_fvu)] = 0\n",
    "young_sort = np.argsort(young_fvu)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "best_young = forest.output_features[young_sort[:10]]\n",
    "best_young"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "old_fvu = (old_self+1)/(old_parent+1)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print(young_fvu[young_sort[:10]])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print(old_fvu[young_sort[:10]])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "top_indices = [n.filter.reduction.features[0] for n in forest.split_clusters[27].nodes]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}

