{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "from suno_utils.utils.text import read_jsonl"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "      index                                  id_x              created_at  \\\n",
      "0   1964552  8da17e3f-3b7b-423d-88e6-3eb3b809928a 2024-11-20 18:25:06.433   \n",
      "1   8795886  be1fc697-e8ca-47b2-94b6-6be632f31edd 2024-11-20 18:25:06.433   \n",
      "4  45513479  8ab114c9-c229-4451-802a-a47ab9425927 2024-11-28 06:21:06.214   \n",
      "5   8982344  43b5e2e3-0c32-40eb-894f-6dfbf6d778e3 2024-11-28 06:21:06.214   \n",
      "6  36763898  0c2988bd-378c-48b1-a573-8aa26d1ef911 2024-11-25 23:04:59.346   \n",
      "\n",
      "                updated_at  time_used  \\\n",
      "0  2024-11-20 18:43:46.423  23.656317   \n",
      "1  2024-11-23 20:38:56.488  17.028764   \n",
      "4  2024-11-28 06:33:00.491  20.288259   \n",
      "5  2024-12-01 03:31:13.357  14.534904   \n",
      "6  2024-11-25 23:09:20.117  26.165704   \n",
      "\n",
      "                                            metadata   user_id    status  \\\n",
      "0  {'tags': 'Dark industrial rock, cumbia, electr...  16190923  complete   \n",
      "1  {'tags': 'Dark industrial rock, cumbia, electr...  16190923  complete   \n",
      "4  {'tags': 'singer/songwriter fusion blues fushi...  48017012  complete   \n",
      "5  {'tags': 'singer/songwriter fusion blues fushi...  48017012  complete   \n",
      "6  {'tags': ' aggresive, emotional, powerful male...  60688389  complete   \n",
      "\n",
      "  discord_message_id prompt_id  ...          id_y  total_play_count  \\\n",
      "0               None      None  ...  1.078901e+12               6.0   \n",
      "1               None      None  ...  1.079366e+12               3.0   \n",
      "4               None      None  ...  1.079016e+12               1.0   \n",
      "5               None      None  ...  1.079315e+12             134.0   \n",
      "6               None      None  ...  1.079315e+12               1.0   \n",
      "\n",
      "  auto_play_count  total_play_time  total_play_count_hour  \\\n",
      "0             0.0       229.982641                    0.0   \n",
      "1             0.0       208.816191                    0.0   \n",
      "4             0.0       200.520000                    0.0   \n",
      "5            88.0     20667.648142                    0.0   \n",
      "6             0.0       225.319979                    0.0   \n",
      "\n",
      "  auto_play_count_hour total_play_time_hour    p_date_y  p_hour_y  \\\n",
      "0                  0.0                  0.0  2024-12-01        22   \n",
      "1                  0.0                  0.0  2024-12-01        22   \n",
      "4                  0.0                  0.0  2024-12-01        22   \n",
      "5                  0.0                  0.0  2024-12-01        22   \n",
      "6                  0.0                  0.0  2024-12-01        22   \n",
      "\n",
      "  norm_play_frac  \n",
      "0       1.281955  \n",
      "1       1.163970  \n",
      "4       0.999601  \n",
      "5     103.029153  \n",
      "6       1.000000  \n",
      "\n",
      "[5 rows x 68 columns]\n"
     ]
    }
   ],
   "source": [
    "base_filepath = \"/home/tony/Data/Preference/up_v1/interesting_clips_up_u_1_20241201_full.pkl\"\n",
    "base_metas = pd.read_pickle(base_filepath)\n",
    "\n",
    "print(base_metas.head())\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Index(['index', 'id_x', 'created_at', 'updated_at', 'time_used', 'metadata',\n",
      "       'user_id', 'status', 'discord_message_id', 'prompt_id', 'request_id',\n",
      "       'is_generated', 's3_id', 'upvote_count', 'batch_index', 'model_name',\n",
      "       'prompt_text', 'daily_theme_id', 'is_deleted', 'image_s3_id',\n",
      "       'is_public', 'dislike_count', 'flag_count', 'play_count', 'skip_count',\n",
      "       'title', 'slug', 'p_date_x', 'p_hour_x', 'continued_parent', 'duration',\n",
      "       'source', 'clip_type', 'task', 'is_pro_user', 'is_in_playlist',\n",
      "       'has_stems', 'user_n_clips', 'upvoted', 'downvoted', 'has_continued',\n",
      "       'part_of_concat', 'has_action', 'flagged', 'deleted', 'pos_preference',\n",
      "       'neg_preference', 'diff_preference', 'preference',\n",
      "       'reaction_play_count', 'reaction_pro_play_count', 'total_start_s',\n",
      "       'total_clip_s', 'concat_play_counts', 'concat_in_playlist',\n",
      "       'concat_likes', 'concat_dislikes', 'str_id', 'id_y', 'total_play_count',\n",
      "       'auto_play_count', 'total_play_time', 'total_play_count_hour',\n",
      "       'auto_play_count_hour', 'total_play_time_hour', 'p_date_y', 'p_hour_y',\n",
      "       'norm_play_frac', 'bass_ratio', 'mid_ratio', 'high_ratio',\n",
      "       'spectral_centroid', 'stereo_width', 'total_clips', 'clips_per_second',\n",
      "       'loudness_factor'],\n",
      "      dtype='object')\n"
     ]
    }
   ],
   "source": [
    "print(base_metas.columns)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# histogram of duration\n",
    "plt.hist(base_metas[\"duration\"], bins=100)\n",
    "plt.show()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Index([     326,      440,      754,      938,     1719,     1738,     1954,\n",
      "           2011,     2040,     2087,\n",
      "       ...\n",
      "       62648697, 62649249, 62653842, 62660198, 62661119, 62661717, 62663095,\n",
      "       62670783, 62674872, 62684836],\n",
      "      dtype='int32', name='user_id', length=42449)\n",
      "[8 2 6 ... 6 2 2]\n",
      "user_id\n",
      "3703765     216\n",
      "23989209    138\n",
      "7160        134\n",
      "27113270    128\n",
      "13323638    124\n",
      "35754448    116\n",
      "19918355    106\n",
      "60578003    104\n",
      "44950622    104\n",
      "43864       102\n",
      "dtype: int64\n"
     ]
    }
   ],
   "source": [
    "user_counts = base_metas.groupby('user_id').size()\n",
    "\n",
    "print(user_counts.index)\n",
    "print(user_counts.values)\n",
    "\n",
    "user_counts_sorted = user_counts.sort_values(ascending=False)\n",
    "#print first 10\n",
    "print(user_counts_sorted.head(10))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAABdEAAAMWCAYAAAAeaM88AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy80BEi2AAAACXBIWXMAAA9hAAAPYQGoP6dpAAB2oklEQVR4nOzdeXxddZ0//tdN0pbS1UJLqYUWSlll32URBCmlCAgoOCiLCI6CICBaFNlEWURFlM35jiD+UGdgFEeQAiMIKosWyiBSyr5ZCmVpCy20JDm/P5hckiYnucGUhPJ8Ph59QD73c+59v0/uOZ/eV05PKkVRFAEAAAAAANqp6+0CAAAAAACgrxKiAwAAAABACSE6AAAAAACUEKIDAAAAAEAJIToAAAAAAJQQogMAAAAAQAkhOgAAAAAAlBCiAwAAAABACSE6AAAAAACUEKIDAEAf8Ic//CGVSiVXX311b5fSay6//PJUKpVMnz69t0upycMPP5zddtstw4YNS6VSyTXXXNPbJb1jWt6vf/jDH3q7FACAZU6IDgDQh1UqlZr+vBNB1sUXX5yPf/zjWX311VOpVHLooYeWzp03b16OPPLIjBw5MoMGDcrOO++ce+65p8O5//3f/53NNtssK6ywQlZfffWceuqpaWxs7LKergLXPffcM+PHj6+ltfeU0047LZVKJausskoWLVrU7vHx48dnzz337IXK3n0OOeSQ/O1vf8u3vvWt/OxnP8sWW2zR4bwnnniizfFaV1eXESNGZPLkybnjjjve4aoBAOiuht4uAACAcj/72c/afH3FFVfkpptuaje+3nrrLfNazjnnnLzyyivZaqut8uyzz5bOa25uzpQpU/K///u/OfHEE7Pyyivnoosuyk477ZS77747EydOrM69/vrrs88++2SnnXbKD3/4w/ztb3/LmWeemeeffz4XX3zxMu/pvaxlH59wwgm9Xcq70muvvZY77rgjX//613P00UfXtM0nP/nJ7LHHHmlqaspDDz2Uiy66KDvvvHP++te/ZsMNN1zGFQMA8HYJ0QEA+rBPfepTbb6+8847c9NNN7Ubfyfceuut1avQBw8eXDrv6quvzu23356rrroq+++/f5LkE5/4RNZee+2ceuqp+fnPf16d++UvfzkbbbRRbrzxxjQ0vPlX06FDh+bb3/52jj322Ky77rrLtqke1NjYmObm5vTv37+3S6nJJptsku985zv5whe+kIEDB/Z2Oe+ohQsXZtCgQf/Uc8ydOzdJMnz48Jq32WyzzdocuzvssEMmT56ciy++OBdddNE/VU9PK4oir7/++nvuvQEA0BG3cwEAeJdbuHBhTjjhhKy22moZMGBA1llnnZx33nkpiqLNvEqlkqOPPjpXXnll1llnnaywwgrZfPPNc9ttt9X0OuPGjUulUuly3tVXX51VVlkl++67b3Vs5MiR+cQnPpHf/OY3Wbx4cZLkgQceyAMPPJAjjzyyGqAnyRe+8IUURbFM7g3+y1/+MptvvnmGDBmSoUOHZsMNN8wPfvCDNnPmzZuXL33pS9X9udZaa+Wcc85Jc3NzdU7L7TnOO++8nH/++ZkwYUIGDBiQBx54IEnywx/+MBtssEFWXHHFvO9978sWW2zR5ocHnWlqasrXvva1jB49OoMGDcpee+2Vp59+uvr4qaeemn79+lVD3NaOPPLIDB8+PK+//nqXr3PKKafkueee6/KK/7J7X7fsg8svv7w6duihh2bw4MF56qmnsueee2bw4MF5//vfnwsvvDBJ8re//S0f/vCHM2jQoIwbN650nyxatCif+9znstJKK2Xo0KE5+OCD8/LLL7ebd/3112eHHXbIoEGDMmTIkEyZMiV///vf28xpqenRRx/NHnvskSFDhuSggw7qtOcZM2Zk8uTJGTp0aAYPHpxddtkld955Z/Xx0047LePGjUuSnHjiialUKm/r1kE77LBDkuTRRx9tM17LezB58199/OAHP8iGG26YFVZYISNHjszuu+/e5hZHjY2N+eY3v1l9j44fPz5f+9rXqsdhi5bb+Nxwww3ZYostMnDgwFx66aVJkmeeeSb77LNPBg0alFGjRuW4445rt33y5j3i99tvv4wePTorrLBCxo4dmwMPPDDz58/v9r4BAOhLXIkOAPAuVhRF9tprr9xyyy05/PDDs8kmm+SGG27IiSeemH/84x/5/ve/32b+rbfemv/4j//IMccckwEDBuSiiy7K7rvvnr/85S/5wAc+0CM1zZgxI5tttlnq6tper7HVVlvlxz/+cR566KFsuOGGmTFjRpK0u4/0mDFjMnbs2OrjPeWmm27KJz/5yeyyyy4555xzkiQzZ87Mn//85xx77LFJ3gxvP/ShD+Uf//hHPve5z2X11VfP7bffnpNOOinPPvtszj///DbPedlll+X111/PkUcemQEDBmTEiBH5t3/7txxzzDHZf//9c+yxx+b111/Pfffdl7vuuiv/8i//0mWd3/rWt1KpVPLVr341zz//fM4///zsuuuuuffeezNw4MB8+tOfzhlnnJH/+I//aHMbkSVLluTqq6/OfvvtlxVWWKHL19lhhx3y4Q9/OOeee24+//nP99gVx01NTZk8eXJ23HHHnHvuubnyyitz9NFHZ9CgQfn617+egw46KPvuu28uueSSHHzwwdl2222zxhprtHmOo48+OsOHD89pp52WWbNm5eKLL86TTz5ZDfSTN291dMghh2TSpEk555xzsmjRolx88cXZfvvtM2PGjDahdmNjYyZNmpTtt98+5513XlZcccXS+v/+979nhx12yNChQ/OVr3wl/fr1y6WXXpqddtopt956a7beeuvsu+++GT58eI477rjqLVo6+9cZZZ544okkyfve977qWHfeg4cffnguv/zyTJ48OZ/97GfT2NiYP/7xj7nzzjurx9VnP/vZ/PSnP83++++fE044IXfddVfOOuuszJw5M7/+9a/b1DNr1qx88pOfzOc+97kcccQRWWeddfLaa69ll112yVNPPZVjjjkmY8aMyc9+9rPcfPPNbbZdsmRJJk2alMWLF+eLX/xiRo8enX/84x+59tprM2/evAwbNqzb+wcAoM8oAAB41zjqqKOK1n+Fu+aaa4okxZlnntlm3v77719UKpXikUceqY4lKZIU06dPr449+eSTxQorrFB87GMf61YdgwYNKg455JDSxz7zmc+0G7/uuuuKJMW0adOKoiiK73znO0WS4qmnnmo3d8sttyy22WabTmu47LLLiiTFX//61w4fnzJlSjFu3Ljq18cee2wxdOjQorGxsfQ5v/nNbxaDBg0qHnrooTbjU6dOLerr66u1Pv7440WSYujQocXzzz/fZu7ee+9dbLDBBp3W3pFbbrmlSFK8//3vLxYsWFAd/8///M8iSfGDH/ygOrbtttsWW2+9dZvtf/WrXxVJiltuuaXT1zn11FOLJMXcuXOLW2+9tUhSfO9736s+Pm7cuGLKlCnt6lr6eVv2wWWXXVYdO+SQQ4okxbe//e3q2Msvv1wMHDiwqFQqxS9/+cvq+IMPPlgkKU499dTqWMv3dPPNNy+WLFlSHT/33HOLJMVvfvOboiiK4pVXXimGDx9eHHHEEW1qmjNnTjFs2LA24y01TZ06tdP90mKfffYp+vfvXzz66KPVsdmzZxdDhgwpdtxxx3b9f+c73+nyOVvmnn766cXcuXOLOXPmFH/84x+LLbfcskhSXHXVVdW5tb4Hb7755iJJccwxx7R7vebm5qIoiuLee+8tkhSf/exn2zz+5S9/uUhS3HzzzdWxcePGtTk+W5x//vlFkuI///M/q2MLFy4s1lprrTbvixkzZrTrBQBgeeF2LgAA72K/+93vUl9fn2OOOabN+AknnJCiKHL99de3Gd92222z+eabV79effXVs/fee+eGG25IU1NTj9T02muvZcCAAe3GW66Ofu2119r8t2xuy+M9Zfjw4Vm4cGFuuumm0jlXXXVVdthhh7zvfe/LCy+8UP2z6667pqmpqd2tb/bbb7+MHDmy3es888wz+etf//q26jz44IMzZMiQ6tf7779/Vl111fzud79rM+euu+5qcxuQK6+8Mquttlo+9KEP1fxaO+64Y3beeeece+65Pbq/P/vZz1b/f/jw4VlnnXUyaNCgfOITn6iOr7POOhk+fHgee+yxdtsfeeSR6devX/Xrz3/+82loaKjug5tuuinz5s3LJz/5yTbfp/r6+my99da55ZZb2j3n5z//+S7rbmpqyo033ph99tkna665ZnV81VVXzb/8y7/kT3/6UxYsWFDbTujAqaeempEjR2b06NHZYYcdMnPmzHz3u9+t/u6ApPb34H/913+lUqnk1FNPbfc6LVfrt+yv448/vs3jLb9M9rrrrmszvsYaa2TSpEltxn73u99l1VVXbVPjiiuumCOPPLLNvJYrzW+44YYsWrSo9p0CAPAuIEQHAHgXe/LJJzNmzJg2oWuSrLfeetXHW5s4cWK751h77bWzaNGiDu+x/XYMHDiww/slt9ynu+W2IS3/LZvbE7cXaX0P9y984QtZe+21M3ny5IwdOzaf+cxnMm3atDbzH3744UybNi0jR45s82fXXXdNkjz//PNt5i99G5Ik+epXv5rBgwdnq622ysSJE3PUUUflz3/+c801L/09qlQqWWuttaq3/kiSAw44IAMGDMiVV16ZJJk/f36uvfbaHHTQQTXdt7610047LXPmzMkll1zSre3KtNybu7Vhw4Zl7Nix7WobNmxYh/c6X3ofDB48OKuuump1Hzz88MNJkg9/+MPtvlc33nhju+9TQ0NDxo4d22Xtc+fOzaJFi7LOOuu0e2y99dZLc3Nzm/vTd9eRRx6Zm266Kb/97W9z3HHH5bXXXmv3w6ta34OPPvpoxowZkxEjRpS+3pNPPpm6urqstdZabcZHjx6d4cOHtzs/dPR+fvLJJ7PWWmu1+94tvY/WWGONHH/88fl//+//ZeWVV86kSZNy4YUXuh86ALBccE90AAB61Kqrrppnn3223XjL2JgxY6rzWsZXW221dnO32mqrTl9n6Svbl7Zo0aI29wYfNWpU7r333txwww25/vrrc/311+eyyy7LwQcfnJ/+9KdJ3vxFjR/5yEfyla98pcPnXHvttdt83VHQv95662XWrFm59tprM23atPzXf/1XLrroopxyyik5/fTTO+2pVu973/uy55575sorr8wpp5ySq6++OosXL86nPvWpbj/XjjvumJ122innnntu/vVf/7Xd42WhfNm/XKivr+/WeLHUL8CtRcsv2PzZz36W0aNHt3u89S+qTd781w5L36O/N0ycOLEahu+5556pr6/P1KlTs/POO1fvYd7d92Atav3Byj/7g6vvfve7OfTQQ/Ob3/wmN954Y4455picddZZufPOO2v6IQYAQF8lRAcAeBcbN25c/ud//ievvPJKm6vRH3zwwerjrbVcwdvaQw89lBVXXLHd1cNv1yabbJI//vGPaW5ubhNc3nXXXVlxxRWrIeAmm2ySJJk+fXqbwHz27Nl55pln2t0uYmktvc2aNSs77LBDu8cfeuihdr8stX///vnoRz+aj370o2lubs4XvvCFXHrppfnGN76RtdZaKxMmTMirr75aDTrfrkGDBuWAAw7IAQcckCVLlmTffffNt771rZx00kld/tLPpb9HRVHkkUceyUYbbdRm/OCDD87ee++dv/71r7nyyiuz6aabZoMNNnhb9Z522mnZaaedcumll7Z7rOWXXs6bN6/N+NJXMfekhx9+ODvvvHP161dffTXPPvts9thjjyTJhAkTkrz5g5F/9nvV2siRI7Piiitm1qxZ7R578MEHU1dX1+4HPv+Mr3/96/m3f/u3nHzyydV/FVHre3DChAm54YYb8tJLL5VejT5u3Lg0Nzfn4Ycfrv7rlCR57rnnMm/evHbnh7LnuP/++1MURZswvqN9lCQbbrhhNtxww5x88sm5/fbbs9122+WSSy7JmWee2eVrAQD0Vb1/OQYAAG/bHnvskaampvzoRz9qM/79738/lUolkydPbjN+xx135J577ql+/fTTT+c3v/lNdtttt9Irhbtr//33z3PPPZdf/epX1bEXXnghV111VT760Y9W74G+wQYbZN11182Pf/zjNlc1X3zxxalUKm3uwdyRzTffPKNGjcr/+3//r90tYa655pr84x//aNP/iy++2GZOXV1dNZhu2f4Tn/hE7rjjjtxwww3tXm/evHlpbGzssv+lX6d///5Zf/31UxRF3njjjS63v+KKK/LKK69Uv7766qvz7LPPtvteTp48OSuvvHLOOeec3HrrrW/rKvQWH/rQh7LTTjvlnHPOqd52p8W4ceNSX1/f7n7wF1100dt+va78+Mc/brOvLr744jQ2Nlb3waRJkzJ06NB8+9vf7nCfvt1bE9XX12e33XbLb37zmza3z3nuuefy85//PNtvv32GDh36tp67I8OHD8/nPve53HDDDbn33nuT1P4e3G+//VIURYf/uqHl6v6WHzqcf/75bR7/3ve+lySZMmVKlzXusccemT17dq6++urq2KJFi/LjH/+4zbwFCxa0Oz423HDD1NXVdXjLJgCAdxNXogMAvIt99KMfzc4775yvf/3reeKJJ7LxxhvnxhtvzG9+85t86Utfql6x2+IDH/hAJk2alGOOOSYDBgyoBqG13Gbkt7/9bf73f/83SfLGG2/kvvvuq15dutdee1UD6f333z/bbLNNDjvssDzwwANZeeWVc9FFF6Wpqand63znO9/JXnvtld122y0HHnhg7r///vzoRz/KZz/72TZXznakf//+Oe+883LIIYdkyy23zAEHHJCVVlopM2bMyE9+8pNstNFGba5m/+xnP5uXXnopH/7whzN27Ng8+eST+eEPf5hNNtmk+lonnnhi/vu//zt77rlnDj300Gy++eZZuHBh/va3v+Xqq6/OE088kZVXXrnTunbbbbeMHj062223XVZZZZXMnDkzP/rRjzJlypR2967vyIgRI7L99tvnsMMOy3PPPZfzzz8/a621Vo444og28/r165cDDzwwP/rRj1JfX59PfvKTXT53Z0499dQ2V3+3GDZsWD7+8Y/nhz/8YSqVSiZMmJBrr7223X3He9KSJUuyyy675BOf+ERmzZqViy66KNtvv3322muvJMnQoUNz8cUX59Of/nQ222yzHHjggRk5cmSeeuqpXHfdddluu+3a/WCpVmeeeWZuuummbL/99vnCF76QhoaGXHrppVm8eHHOPffcnmwzSXLsscfm/PPPz9lnn51f/vKXNb8Hd95553z605/OBRdckIcffji77757mpub88c//jE777xzjj766Gy88cY55JBD8uMf/zjz5s3Lhz70ofzlL3/JT3/60+yzzz4dfr+XdsQRR+RHP/pRDj744Nx9991ZddVV87Of/Swrrrhim3k333xzjj766Hz84x/P2muvncbGxvzsZz9LfX199ttvvx7fbwAA76gCAIB3jaOOOqpY+q9wr7zySnHccccVY8aMKfr161dMnDix+M53vlM0Nze3mZekOOqoo4r/7//7/4qJEycWAwYMKDbddNPilltuqem1DznkkCJJh38uu+yyNnNfeuml4vDDDy9WWmmlYsUVVyw+9KEPFX/96187fN5f//rXxSabbFIMGDCgGDt2bHHyyScXS5YsqXmfXH/99cXOO+9cDB06tOjXr1+xxhprFMcff3zx8ssvt5l39dVXF7vttlsxatSoon///sXqq69efO5znyueffbZNvNeeeWV4qSTTirWWmuton///sXKK69cfPCDHyzOO++8al2PP/54kaT4zne+066eSy+9tNhxxx2LlVZaqRgwYEAxYcKE4sQTTyzmz5/faR+33HJLkaT4xS9+UZx00knFqFGjioEDBxZTpkwpnnzyyQ63+ctf/lIkKXbbbbea99epp55aJCnmzp3b7rEPfehDRZJiypQpbcbnzp1b7LfffsWKK65YvO997ys+97nPFffff3+77/0hhxxSDBo0qMPn3WCDDdqNjxs3rs1rXXbZZUWS4tZbby2OPPLI4n3ve18xePDg4qCDDipefPHFdtvfcsstxaRJk4phw4YVK6ywQjFhwoTi0EMPLaZPn95lTZ255557ikmTJhWDBw8uVlxxxWLnnXcubr/99jZzOnsPLK2ruYceemhRX19fPPLII0VR1PYeLIqiaGxsLL7zne8U6667btG/f/9i5MiRxeTJk4u77767OueNN94oTj/99GKNNdYo+vXrV6y22mrFSSedVLz++uttalj6e9Hak08+Wey1117FiiuuWKy88srFscceW0ybNq1IUj1/PPbYY8VnPvOZYsKECcUKK6xQjBgx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Mi0KAAAAAAD6gpruib7JJpvksMMOy/bbb5+iKHLeeedl8ODBHc495ZRTerRAAAAAAADoLTWF6JdffnlOPfXUXHvttalUKrn++uvT0NB+00qlIkQHAAAAAGC5UVOIvs466+SXv/xlkqSuri6///3vM2rUqGVaGAAAAAAA9LaaQvTWmpubl0UdAAAAAADQ53Q7RE+SRx99NOeff35mzpyZJFl//fVz7LHHZsKECT1aHAAAAAAA9Ka67m5www03ZP31189f/vKXbLTRRtloo41y1113ZYMNNshNN920LGoEAAAAAIBe0e0r0adOnZrjjjsuZ599drvxr371q/nIRz7SY8UBAAAAAEBv6vaV6DNnzszhhx/ebvwzn/lMHnjggR4pCgAAAAAA+oJuh+gjR47Mvffe22783nvvzahRo3qiJgAAAAAA6BO6fTuXI444IkceeWQee+yxfPCDH0yS/PnPf84555yT448/vscLBAAAAACA3tLtEP0b3/hGhgwZku9+97s56aSTkiRjxozJaaedlmOOOabHCwQAAAAAgN7S7RC9UqnkuOOOy3HHHZdXXnklSTJkyJAeLwwAAAAAAHpbt0P01oTnAAAAAAAsz7r9i0UBAAAAAOC9QogOAAAAAAAlhOgAAAAAAFCiWyH6G2+8kV122SUPP/zwsqoHAAAAAAD6jG6F6P369ct99923rGoBAAAAAIA+pdu3c/nUpz6Vf//3f18WtQAAAAAAQJ/S0N0NGhsb85Of/CT/8z//k8033zyDBg1q8/j3vve9HisOAAAAAAB6U7dD9Pvvvz+bbbZZkuShhx5q81ilUumZqgAAAAAAoA/odoh+yy23LIs6AAAAAACgz+n2PdFbPPLII7nhhhvy2muvJUmKouixogAAAAAAoC/odoj+4osvZpdddsnaa6+dPfbYI88++2yS5PDDD88JJ5zQ4wUCAAAAAEBv6XaIftxxx6Vfv3556qmnsuKKK1bHDzjggEybNq1HiwMAAAAAgN7U7Xui33jjjbnhhhsyduzYNuMTJ07Mk08+2WOFAQAAAABAb+v2legLFy5scwV6i5deeikDBgzokaIAAAAAAKAv6PaV6DvssEOuuOKKfPOb30ySVCqVNDc359xzz83OO+/c4wVCXzV+6nU1z33i7CnLsBIAAAAAYFnpdoh+7rnnZpdddsn06dOzZMmSfOUrX8nf//73vPTSS/nzn/+8LGoEAAAAAIBe0e3buXzgAx/IQw89lO233z577713Fi5cmH333TczZszIhAkTlkWNAAAAAADQK7p9JXqSDBs2LF//+td7uhYAAAAAAOhT3laI/vLLL+ff//3fM3PmzCTJ+uuvn8MOOywjRozo0eIAAAAAAKA3dft2LrfddlvGjx+fCy64IC+//HJefvnlXHDBBVljjTVy2223LYsaAQAAAACgV3T7SvSjjjoqBxxwQC6++OLU19cnSZqamvKFL3whRx11VP72t7/1eJGwvBg/9bqa5j1x9pR/ahsAAAAAoGd0+0r0Rx55JCeccEI1QE+S+vr6HH/88XnkkUd6tDgAAAAAAOhN3Q7RN9tss+q90FubOXNmNt544x4pCgAAAAAA+oKabudy3333Vf//mGOOybHHHptHHnkk22yzTZLkzjvvzIUXXpizzz572VQJAAAAAAC9oKYQfZNNNkmlUklRFNWxr3zlK+3m/cu//EsOOOCAnqsOAAAAAAB6UU0h+uOPP76s6wAAAAAAgD6nphB93Lhxy7oOoAeNn3pdTfOeOHvKP7UNAAAAACzvagrRlzZ79uz86U9/yvPPP5/m5uY2jx1zzDE9UhgAAAAAAPS2uu5ucPnll2eNNdbI4YcfnvPOOy/f//73q3/OP//8bj3Xbbfdlo9+9KMZM2ZMKpVKrrnmmjaPF0WRU045JauuumoGDhyYXXfdNQ8//HCbOS+99FIOOuigDB06NMOHD8/hhx+eV199tbttAQAAAABAO90O0b/xjW/klFNOyfz58/PEE0/k8ccfr/557LHHuvVcCxcuzMYbb5wLL7yww8fPPffcXHDBBbnkkkty1113ZdCgQZk0aVJef/316pyDDjoof//733PTTTfl2muvzW233ZYjjzyyu20BAAAAAEA73b6dy6JFi3LggQemrq7b+Xs7kydPzuTJkzt8rCiKnH/++Tn55JOz9957J0muuOKKrLLKKrnmmmty4IEHZubMmZk2bVr++te/ZosttkiS/PCHP8wee+yR8847L2PGjPmnawQAAAAA4L2r2yH64YcfnquuuipTp05dFvVUPf7445kzZ0523XXX6tiwYcOy9dZb54477siBBx6YO+64I8OHD68G6Emy6667pq6uLnfddVc+9rGPdfjcixcvzuLFi6tfL1iwIEnS2NiYxsbGJEldXV3q6urS3Nzc5r7vLeNNTU0piqLL8fr6+lQqlerzth5PkqampprGGxoaUhRFm/FKpZL6+vp2NZaNd9ZTkjRUilQqb71mU3PSnEqb8cbGxmpP/ere6jNJGpuTIkm/pX6+0rI/mpqa2mzzRnMllRRpqGs9N2ksKm1q7FdXVMfrKkXqW9XYXCRNRSX1laK6j/vVFWkqkuai0mVPLdtUUqRIbT1V98FStXfWU5I0Nze3ef7OemqZ33qbrnpq/d7rV1f8X+2d99T2fVmkknTZU2NjY4++95bH40lPetKTnvSkJz3pSU960pOe9KQnPelJT32/p9bbd6bbIfpZZ52VPffcM9OmTcuGG26Yfv36tXn8e9/7XnefskNz5sxJkqyyyiptxldZZZXqY3PmzMmoUaPaPN7Q0JARI0ZU53TkrLPOyumnn95ufMaMGRk0aFCSZOTIkZkwYUIef/zxzJ07tzpn7NixGTt2bB566KHMnz+/Or7mmmtm1KhRuf/++/Paa69Vx9ddd90MHz48M2bMaPON2mijjdK/f/9Mnz69TQ1bbLFFlixZkvvuu686Vl9fny233DLz58/Pgw8+WB0fOHBgNt5447zwwgttbqUzbNiwrLfeepk9e3aeeeaZ6nhnPSXJR8Y2Z+yKb9Vy25xKZs2v5GPjmzO8/5tj06dPr/Z00ITmNuHy1Y/X5dXG5NCJbX/ZbFNTU7WnlsfeaE4uf7g+7x+UTB771vx5S5KrHq9v09OhE5vzzKLk+qfrs+lKRTZb6a0396z5ldw2p5LtVimq+/LQic2558VK7n6h0mVPLdu8f1DyzMLU1NP06dOzxRZbZHj/ZP813hrvrKckeeGFF9o8T2c9Jal+n1q26aqn1u+9Qyc25/pn6rrsqfX7r19dMrih656mT59efe9NPue67Dj6rdpbetp85eY2PR244wbvqeNJT3rSk570pCc96UlPetKTnvSkJz3pSU99v6fW23emUtQat/+fM888M6ecckrWWWedrLLKKqm0uiS2Uqnk5ptv7s7Ttdn217/+dfbZZ58kye23357tttsus2fPzqqrrlqd94lPfCKVSiX/8R//kW9/+9v56U9/mlmzZrV5rlGjRuX000/P5z//+Q5fq6Mr0VdbbbW8+OKLGTp0aJL33k911vza9TVdiT7zjN2rPU382rVtaiy7Ev2hb02p9rTeKdOq451dif7YtydXa1zvlGk1XYk+65u7V+fXeiX6zDPe3GbiydNqvhK9ZR+sedJ1NV+J/shZe6a5uTnrnPy7dr121NOj/ze/ubm5us+66unRb+1efe+td8q0mq5Eb+k/SdY6eVpNV6LPPGP36ntszanXpr6D79/SPc06c4/31PGkJz3pSU960pOe9KQnPelJT3rSk570pKe+39OCBQsyfPjwzJ8/v5oLd6TbV6J/97vfzU9+8pMceuih3d20W0aPHp0kee6559qE6M8991w22WST6pznn3++zXaNjY156aWXqtt3ZMCAARkwYEC78YaGhjQ0tN0lLd+UpbXs/FrHl37etzNeqVQ6HC+rsbvjjUXlzXS1k/HWr/9Gc6X95Lx59fLSdbdsu/Q2RSrt5i9dY+ttmotK9XYnrTUVb+2b1vO76qllmzdvZFJbT6236aj2znrq6PnLemrZB0tvU9ZT6/de620666nt+6mSIu2/f0nbnlpv05xKmjuYv3RPLd/L99LxpCc9lY3rSU+Jnspq7O64nvSU6Kmsxu6O60lPiZ7KauzuuJ70lOiprMbujutJT8my7an1BeKd6fZvBx0wYEC222677m7WbWussUZGjx6d3//+99WxBQsW5K677sq2226bJNl2220zb9683H333dU5N998c5qbm7P11lsv8xoBAAAAAFi+dTtEP/bYY/PDH/6wR1781Vdfzb333pt77703yZv3gL733nvz1FNPpVKp5Etf+lLOPPPM/Pd//3f+9re/5eCDD86YMWOqt3xZb731svvuu+eII47IX/7yl/z5z3/O0UcfnQMPPDBjxozpkRoBAAAAAHjv6vbtXP7yl7/k5ptvzrXXXpsNNtig3S8W/dWvflXzc02fPj0777xz9evjjz8+SXLIIYfk8ssvz1e+8pUsXLgwRx55ZObNm5ftt98+06ZNyworrFDd5sorr8zRRx+dXXbZJXV1ddlvv/1ywQUXdLctAAAAAABop9sh+vDhw7Pvvvv2yIvvtNNObW7+vrRKpZIzzjgjZ5xxRumcESNG5Oc//3mP1AMse+OnXlfTvCfOnrKMKwEAAACArnU7RL/sssuWRR0AAAAAANDndPue6AAAAAAA8F7R7SvR11hjjVQqldLHH3vssX+qIAAAAAAA6Cu6HaJ/6UtfavP1G2+8kRkzZmTatGk58cQT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AABACSE6AAAAAACUEKIDAAAAAEAJIToAAAAAAJQQogMAAAAAQAkhOgAAAAAAlBCiAwAAAABACSE6AAAAAACUEKIDAAAAAEAJIToAAAAAAJQQogMAAAAAQAkhOgAAAAAAlBCiAwAAAABACSE6AAAAAACUEKIDAAAAAEAJIToAAAAAAJQQogMAAAAAQAkhOgAAAAAAlBCiAwAAAABACSE6AAAAAACUEKIDAAAAAEAJIToAAAAAAJQQogMAAAAAQAkhOgAAAAAAlBCiAwAAAABACSE6AAAAAACUEKIDAAAAAEAJIToAAAAAAJQQogMAAAAAQAkhOgAAAAAAlBCiAwAAAABACSE6AAAAAACUEKIDAAAAAEAJIToAAAAAAJQQogMAAAAAQAkhOgAAAAAAlBCiAwAAAABACSE6AAAAAACUEKIDAAAAAEAJIToAAAAAAJQQogMAAAAAQAkhOgAAAAAAlBCiAwAAAABACSE6AAAAAACUEKIDAAAAAEAJIToAAAAAAJQQogMAAAAAQAkhOgAAAAAAlBCiAwAAAABACSE6AAAAAACUEKIDAAAAAEAJIToAAAAAAJQQogMAAAAAQAkhOgAAAAAAlBCiAwAAAABACSE6AAAAAACUEKIDAAAAAEAJIToAAAAAAJQQogMAAAAAQAkhOgAAAAAAlBCiAwAAAABACSE6AAAAAACUEKIDAAAAAEAJIToAAAAAAJQQogMAAAAAQAkhOgAAAAAAlBCiAwAAAABACSE6AAAAAACUEKIDAAAAAEAJIToAAAAAAJQQogMAAAAAQAkhOgAAAAAAlBCiAwAAAABACSE6AAAAAACUEKIDAAAAAEAJIToAAAAAAJQQogMAAAAAQAkhOgAAAAAAlBCiAwAAAABACSE6AAAAAACUEKIDAAAAAEAJIToAAAAAAJQQogMAAAAAQAkhOgAAAAAAlBCiAwAAAABACSE6AAAAAACUEKIDAAAAAEAJIToAAAAAAJQQogMAAAAAQAkhOgAAAAAAlBCiAwAAAABACSE6AAAAAACUEKIDAAAAAEAJIToAAAAAAJQQogMAAAAAQAkhOgAAAAAAlBCiAwAAAABACSE6AAAAAACUEKIDAAAAAEAJIToAAAAAAJQQogMAAAAAQAkhOgAAAAAAlBCiAwAAAABACSE6AAAAAACUEKIDAAAAAEAJIToAAAAAAJQQogMA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xYsXZ8CAAWlsbEy/fv16u5x3VKV4r/3YgA7NmjUrW2+9dSZPnpzx48fn+uuvT79+/fLpT386xxxzTG+XB7yD7rvvvuy1114ZMGBAnnvuuay66qo55ZRTMmnSpIwYMaK3ywPeAc4DwH333ZdJkyZl5MiRefLJJzN8+PAceeSROeSQQzJ27NjeLg9YxpwDgKX9/e9/zze+8Y288sorqa+vz9e+9rVss80275kfrrmdCymKIldccUUmTZqUX/ziFznrrLPyxz/+Mfvss08uu+yynHvuub1dIvAOmTt3bg444IAcdNBBuf766/PAAw9k4403zje/+c1ccMEFmTt3bm+XCCxjzgPAyy+/nMMOOywHH3xw/ud//icvv/xyPv7xj+e3v/1tvv71r+fJJ5/s7RKBZcg5AFjaww8/nA9+8IMZOXJkNt100wwZMiQ77bRTvv3tb+epp57q7fLeEUJ0UqlUMnv27MyZM6c6NmTIkBxzzDH51Kc+lauuuipXXnllL1YIvFPmzp2b119/Pfvuu2/WXHPNjBkzJr/85S+z11575Ve/+lUuv/zyLFq0qLfLBJYh5wHglVdeyYsvvpjddtsto0aNSl1dXc4777x86lOfysMPP5xzzz03L7zwQm+XCSwjzgHA0q644opss802ufTSS3Puuefmqquuyg9+8IP86Ec/ykUXXZTnnnuut0tc5oTo73Etd/PZbLPN0tTUlFmzZlUfGzJkSD7zmc9k0003zUUXXeQDM7wHvPHGG2lsbKwe76+99lqS5Oyzz87OO++ciy++OI888kgSv2QQlleLFy92HoD3uLq6uqy44oqZPXt2kqSxsTFJcvTRR2fffffNLbfckj//+c9JnAdgeeQcACyt5TNB8tY54Ytf/GK+9a1v5Uc/+lF+/etfJ0mam5t7pb53gnuikyR59NFHs80222SvvfbKD37wgwwePDhFUaRSqeTpp5/OuHHj8rvf/S677757b5cKLGNbbbVVBg8enJtvvjnJW784JEm23HLLrLXWWvnFL37RmyUCPezZZ5/Nyy+/nPXXXz/Jm8f6kCFDnAfgPWTRokVpaGio3td07733ztNPP51bbrklw4YNS2NjYxoaGpIke+yxR15//fXqOQJY/nz0ox/NP/7xD+cAIElywQUX5OSTT86DDz6YMWPGZMmSJdW/M5xxxhn5zne+kwceeCCr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",
      "text/plain": [
       "<Figure size 1500x800 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Get top 100 users\n",
    "top_100 = user_counts_sorted.head(100)\n",
    "\n",
    "# Create bar plot\n",
    "plt.figure(figsize=(15, 8))\n",
    "plt.bar(range(len(top_100)), top_100.values)\n",
    "\n",
    "# Customize plot\n",
    "plt.title('Top 100 Users by Number of Records')\n",
    "plt.xlabel('User Rank')\n",
    "plt.ylabel('Number of Records')\n",
    "\n",
    "# Rotate x-axis labels for better readability\n",
    "plt.xticks(rotation=45)\n",
    "\n",
    "# Add grid for easier reading\n",
    "plt.grid(axis='y', linestyle='--', alpha=0.7)\n",
    "\n",
    "plt.tight_layout()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 104,
   "metadata": {},
   "outputs": [],
   "source": [
    "base_metas = base_metas[base_metas[\"duration\"] >= 30]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "227735\n"
     ]
    }
   ],
   "source": [
    "ap_metas_filepath = \"/home/christian/code/christian/metadata/interesting_clips_up_u_1_20241201_full_audio_production.jsonl\"\n",
    "ap_metas = read_jsonl(ap_metas_filepath)\n",
    "print(len(ap_metas))\n",
    "ap_metas_map = {meta[\"id\"]: meta for meta in ap_metas}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 63,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "        stereo_width                            request_id  pos_preference\n",
      "1954           0.143  0157294f-ffca-4d45-b519-3838066b6b8e           False\n",
      "1955           0.089  0157294f-ffca-4d45-b519-3838066b6b8e            True\n",
      "4540           0.219  02ffaeaf-e6a4-4bc9-b2ff-fbd799d5bc45           False\n",
      "4541           0.332  02ffaeaf-e6a4-4bc9-b2ff-fbd799d5bc45            True\n",
      "7024           0.078  04b3c91d-4528-414e-9a2d-8bb305d20a81           False\n",
      "...              ...                                   ...             ...\n",
      "358875         0.249  f14f75e9-c9c4-40f9-90cf-7b2038e873f5            True\n",
      "365058         0.294  f56c1da4-e378-46d4-b726-498de23d5f1a           False\n",
      "365059         0.278  f56c1da4-e378-46d4-b726-498de23d5f1a            True\n",
      "369002         0.064  f8228629-99db-4af5-bf1e-d2268b69c39f           False\n",
      "369003         0.114  f8228629-99db-4af5-bf1e-d2268b69c39f            True\n",
      "\n",
      "[216 rows x 3 columns]\n"
     ]
    }
   ],
   "source": [
    "# Get user_id with most records\n",
    "top_user_id = user_counts_sorted.index[0]\n",
    "\n",
    "# Get all rows for that user\n",
    "top_user_data = base_metas[base_metas['user_id'] == top_user_id]\n",
    "\n",
    "print(top_user_data[[\"stereo_width\", \"request_id\",\"pos_preference\"]])\n",
    "\n",
    "# add a num column which is the difference in stereo_widthbetween the positive and negative examples, positive are odd index and negative are even stored in order\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 80,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|██████████| 5000/5000 [00:46<00:00, 107.38it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "          positive  negative  mean_stereo_diff  total_comparisons  \\\n",
      "user_id                                                             \n",
      "32682028         5         0          0.334400                  5   \n",
      "62543891         3         2          0.226000                  5   \n",
      "12487481         5         1          0.209833                  6   \n",
      "1650994          7         2          0.199333                  9   \n",
      "24924956         5         1          0.191500                  6   \n",
      "\n",
      "          positive_ratio  \n",
      "user_id                   \n",
      "32682028        1.000000  \n",
      "62543891        0.600000  \n",
      "12487481        0.833333  \n",
      "1650994         0.777778  \n",
      "24924956        0.833333  \n"
     ]
    }
   ],
   "source": [
    "from tqdm import tqdm\n",
    "# Get top 1000 users\n",
    "top_1000_users = user_counts_sorted.index[:5000]\n",
    "\n",
    "# Initialize DataFrame for results\n",
    "all_user_results = pd.DataFrame()\n",
    "\n",
    "# Process top 1000 users\n",
    "for user_id in tqdm(top_1000_users):\n",
    "    user_data = base_metas[base_metas['user_id'] == user_id].reset_index(drop=True)\n",
    "    \n",
    "    if len(user_data) % 2 != 0:\n",
    "        continue\n",
    "        \n",
    "    user_collapsed = pd.DataFrame()\n",
    "    for i in range(0, len(user_data)-1, 2):\n",
    "        diff = user_data.iloc[i+1]['stereo_width'] - user_data.iloc[i]['stereo_width']\n",
    "        row = pd.DataFrame({\n",
    "            'user_id': [user_id],\n",
    "            'request_id': [user_data.iloc[i]['request_id']],\n",
    "            'stereo_width_diff': [diff],\n",
    "            'wider_in': ['positive' if diff > 0 else 'negative']\n",
    "        })\n",
    "        user_collapsed = pd.concat([user_collapsed, row], ignore_index=True)\n",
    "    \n",
    "    all_user_results = pd.concat([all_user_results, user_collapsed], ignore_index=True)\n",
    "\n",
    "# Modified groupby section to include mean stereo_width_diff\n",
    "user_stats = pd.DataFrame({\n",
    "    'positive': all_user_results.groupby('user_id')['wider_in'].apply(lambda x: (x == 'positive').sum()),\n",
    "    'negative': all_user_results.groupby('user_id')['wider_in'].apply(lambda x: (x == 'negative').sum()),\n",
    "    'mean_stereo_diff': all_user_results.groupby('user_id')['stereo_width_diff'].mean()\n",
    "})\n",
    "\n",
    "user_stats['total_comparisons'] = user_stats['positive'] + user_stats['negative']\n",
    "user_stats['positive_ratio'] = user_stats['positive'] / user_stats['total_comparisons']\n",
    "\n",
    "print(user_stats.sort_values('mean_stereo_diff', ascending=False).head())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 88,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "          positive  negative  mean_stereo_diff  total_comparisons  \\\n",
      "user_id                                                             \n",
      "32682028         5         0          0.334400                  5   \n",
      "62543891         3         2          0.226000                  5   \n",
      "12487481         5         1          0.209833                  6   \n",
      "1650994          7         2          0.199333                  9   \n",
      "24924956         5         1          0.191500                  6   \n",
      "1534320          4         2          0.180167                  6   \n",
      "457714           5         1          0.169833                  6   \n",
      "2326982          7         1          0.156250                  8   \n",
      "22104350         5         0          0.152800                  5   \n",
      "24626212         4         1          0.152600                  5   \n",
      "\n",
      "          positive_ratio  \n",
      "user_id                   \n",
      "32682028        1.000000  \n",
      "62543891        0.600000  \n",
      "12487481        0.833333  \n",
      "1650994         0.777778  \n",
      "24924956        0.833333  \n",
      "1534320         0.666667  \n",
      "457714          0.833333  \n",
      "2326982         0.875000  \n",
      "22104350        1.000000  \n",
      "24626212        0.800000  \n"
     ]
    }
   ],
   "source": [
    "print(user_stats.sort_values('mean_stereo_diff', ascending=False).head(10))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 87,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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JSQkaMiQIdGdYDsR6TofO3ZMJSUlysnJkcfj0WWXXcZ/O85BpOs8d+5cff3rX1daWpry8vI0btw4nTx5so1mG582btyo22+/Xbm5uUpISNBLL730hY9Zv369rr76ank8Hn3ta1/TkiVLoj5PufPM8uXLXUpKinvmmWfcrl273KhRo1xmZqarqak56/g333zTJSUluVmzZrndu3e7SZMmuQ4dOridO3e28czjS6TrfM8997iKigq3fft2t2fPHnfvvfe6jIwM98EHH7TxzONLpOt8yv79+91Xv/pV981vftPdcccdbTPZOBbpOtfV1bkBAwa4wYMHuzfeeMPt37/frV+/3u3YsaONZx5fIl3nZcuWOY/H45YtW+b279/vXnvtNZeTk+PGjRvXxjOPL6tXr3aPPPKIe/HFF50kt2LFis8dv2/fPnfBBRe48ePHu927d7v58+e7pKQkt2bNmqjO87wLlGuvvdaVlJSEvm5qanK5ubmurKzsrOPvuusuV1RUFHYsPz/f3XfffVGdZ7yLdJ1P19jY6NLT093SpUujNcV2oSXr3NjY6AYOHOh+97vfuREjRhAo5yDSdV6wYIG75JJLXH19fVtNsV2IdJ1LSkrcjTfeGHZs/PjxbtCgQVGdZ3tyLoHy0EMPucsvvzzs2N133+0KCwujODPnzqsf8dTX16u6uloFBQWhY4mJiSooKFBVVdVZH1NVVRU2XpIKCws/czxats6n+/TTT9XQ0KDOnTtHa5pxr6XrPH36dGVlZWnkyJFtMc2415J1fvnll+X3+1VSUiKfz6crrrhCM2fOVFNTU1tNO+60ZJ0HDhyo6urq0I+B9u3bp9WrV2vw4MFtMufzRay+D8bFbzNuLR999JGamprO+LRan8+nt99++6yPCQQCZx0fCASiNs9415J1Pt3DDz+s3NzcM/6lwP9ryTq/8cYbevrpp7Vjx442mGH70JJ13rdvn9atW6fi4mKtXr1a7733nh544AE1NDRo6tSpbTHtuNOSdb7nnnv00Ucf6frrr5dzTo2NjfrJT36iX/7yl20x5fPGZ30fDAaD+s9//qO0tLSoPO95tYOC+FBeXq7ly5drxYoVSk1NjfV02o3jx49r+PDhWrRokS666KJYT6dda25uVlZWlp566in1799fd999tx555BEtXLgw1lNrV9avX6+ZM2fqySef1LZt2/Tiiy9q1apVmjFjRqynhlZwXu2gXHTRRUpKSlJNTU3Y8ZqaGmVnZ5/1MdnZ2RGNR8vW+ZTZs2ervLxcf/nLX3TllVdGc5pxL9J1/uc//6kDBw7o9ttvDx1rbm6WJCUnJ2vv3r3q2bNndCcdh1ry9zknJ0cdOnRQUlJS6Fjv3r0VCARUX1+vlJSUqM45HrVknSdPnqzhw4frxz/+sSSpb9++OnHihEaPHq1HHnlEiYn8P3hr+Kzvg16vN2q7J9J5toOSkpKi/v37q7KyMnSsublZlZWV8vv9Z32M3+8PGy9Ja9eu/czxaNk6S9KsWbM0Y8YMrVmzRgMGDGiLqca1SNe5V69e2rlzp3bs2BG6ffe739V3vvMd7dixQ3l5eW05/bjRkr/PgwYN0nvvvRcKQEl65513lJOTQ5x8hpas86effnpGhJyKQsevmWs1Mfs+GNWX4Bq0fPly5/F43JIlS9zu3bvd6NGjXWZmpgsEAs4554YPH+5KS0tD4998802XnJzsZs+e7fbs2eOmTp3K24zPQaTrXF5e7lJSUtyf/vQn9+9//zt0O378eKwuIS5Eus6n41085ybSdT548KBLT093Y8aMcXv37nUrV650WVlZ7tFHH43VJcSFSNd56tSpLj093f3hD39w+/btc6+//rrr2bOnu+uuu2J1CXHh+PHjbvv27W779u1OkpszZ47bvn27e//9951zzpWWlrrhw4eHxp96m/GECRPcnj17XEVFBW8zjpb58+e7rl27upSUFHfttde6t956K3TfDTfc4EaMGBE2/vnnn3eXXXaZS0lJcZdffrlbtWpVG884PkWyzt26dXOSzrhNnTq17SceZyL9+/y/CJRzF+k6b9q0yeXn5zuPx+MuueQS99hjj7nGxsY2nnX8iWSdGxoa3K9+9SvXs2dPl5qa6vLy8twDDzzgPv7447afeBz561//etb/3p5a2xEjRrgbbrjhjMf069fPpaSkuEsuucQtXrw46vNMcI59MAAAYMt59RoUAAAQHwgUAABgDoECAADMIVAAAIA5BAoAADCHQAEAAOYQKAAAwBwCBQAAmEOgAAAAcwgUAABgDoECAADMIVAAAIA5/wdqpc7sZoM2ZwAAAABJRU5ErkJggg==",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# make a histogram of the mean_stereo_diff\n",
    "plt.hist(user_stats['positive_ratio'], bins=20)\n",
    "plt.show()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 93,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "    stereo_width                                  id_x  pos_preference\n",
      "0          1.000  8fa5301b-352f-4569-b9fc-7cd76b215548           False\n",
      "1          0.813  4d79df0f-c5b5-4708-9972-61470040b55d            True\n",
      "2          0.367  9feee0ee-92fa-4d0b-93c6-5d63cdfdac9a           False\n",
      "3          0.476  ada4347a-5e5e-406f-b85d-73d90ddfe634            True\n",
      "4          0.459  ab5c1e9b-7f96-45ec-a9c2-e3eec5e07c30           False\n",
      "5          0.686  08cc51b0-39b7-4f49-ba61-9467fb4d3822            True\n",
      "6          0.520  38937a34-4439-44d1-8fa6-1ee804dfae8c           False\n",
      "7          1.000  3a48b73c-8f47-41ea-9d8c-3a8f57a6a5d3            True\n",
      "8          0.492  bf85b945-3115-4034-98cc-4e21eb809763           False\n",
      "9          0.878  fbfdaa64-fc38-45f5-be1e-d1c99e3e6507            True\n",
      "10         0.514  36e7d781-d822-42d5-91cf-bcb003cf221e           False\n",
      "11         0.758  04bff382-4ef3-4c5b-bf11-eda454d17b46            True\n"
     ]
    }
   ],
   "source": [
    "# lets go to the main base_metas and look at the results from user_id 23682257\n",
    "user_id = 12487481\n",
    "user_data = base_metas[base_metas['user_id'] == user_id].reset_index(drop=True)\n",
    "print(user_data[[\"stereo_width\", \"id_x\", \"pos_preference\"]])\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Create mapping dictionary with error handling\n",
    "feature_mapping = {\n",
    "    s3_id: {\n",
    "        key: type_(features[\"features\"].get(key, None))\n",
    "        for key, type_ in {\n",
    "            'bass_ratio': float,\n",
    "            'mid_ratio': float,\n",
    "            'high_ratio': float,\n",
    "            'spectral_centroid': float,\n",
    "            'stereo_width': float,\n",
    "            'total_clips': int,\n",
    "            'clips_per_second': float,\n",
    "            'loudness_factor': float\n",
    "        }.items()\n",
    "    } if \"features\" in features else {}\n",
    "    for s3_id, features in ap_metas_map.items()\n",
    "}\n",
    "\n",
    "features_df = pd.DataFrame.from_dict(feature_mapping, orient='index')\n",
    "base_metas = base_metas.join(features_df, on='id_x')\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Calculate differences between pairs\n",
    "differences = base_metas[base_metas.index % 2 == 1]['stereo_width'].values - base_metas[base_metas.index % 2 == 0]['stereo_width'].values\n",
    "\n",
    "plt.figure(figsize=(10, 6))\n",
    "plt.hist(differences, bins=250)\n",
    "plt.xlabel('Stereo Width Difference (Positive - Negative)')\n",
    "plt.ylabel('Count')\n",
    "plt.title('Distribution of Stereo Width Differences')\n",
    "plt.axvline(x=0, color='r', linestyle='--', alpha=0.5)\n",
    "print(f\"Mean difference: {differences.mean():.4f}\")\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "diff_df = pd.DataFrame({\n",
    "   'id_x_negative': base_metas[base_metas.index % 2 == 0]['id_x'].values,\n",
    "   'id_x_positive': base_metas[base_metas.index % 2 == 1]['id_x'].values,\n",
    "   'stereo_width_diff': (\n",
    "       base_metas[base_metas.index % 2 == 1]['stereo_width'].values - \n",
    "       base_metas[base_metas.index % 2 == 0]['stereo_width'].values\n",
    "   )\n",
    "})\n",
    "\n",
    "plt.figure(figsize=(10, 6))\n",
    "plt.hist(diff_df['stereo_width_diff'], bins=250)\n",
    "plt.xlabel('Stereo Width Difference (Positive - Negative)')\n",
    "plt.ylabel('Count')\n",
    "plt.title('Distribution of Stereo Width Differences')\n",
    "plt.axvline(x=0, color='r', linestyle='--', alpha=0.5)\n",
    "print(f\"Mean difference: {diff_df['stereo_width_diff'].mean():.4f}\")\n",
    "plt.show()\n",
    "\n",
    "print(\"\\nLargest differences:\")\n",
    "print(diff_df.nlargest(5, 'stereo_width_diff'))\n",
    "print(\"\\nSmallest differences:\")\n",
    "print(diff_df.nsmallest(5, 'stereo_width_diff'))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# distribution of loudness_factor from negatives\n",
    "\n",
    "\n",
    "plt.hist(base_metas[base_metas.index % 2 == 0]['high_ratio'], bins=100, alpha=0.5, label='Negative')\n",
    "plt.hist(base_metas[base_metas.index % 2 == 1]['high_ratio'], bins=100, alpha=0.5, label='Positive')\n",
    "plt.legend()\n",
    "plt.show()\n",
    "\n",
    "# distribution of spectral centroid"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "diff_df = pd.DataFrame({\n",
    "   'id_x_negative': base_metas[base_metas.index % 2 == 0]['id_x'].values,\n",
    "   'id_x_positive': base_metas[base_metas.index % 2 == 1]['id_x'].values,\n",
    "   'spectral_centroid_diff': (\n",
    "       base_metas[base_metas.index % 2 == 1]['spectral_centroid'].values - \n",
    "       base_metas[base_metas.index % 2 == 0]['spectral_centroid'].values\n",
    "   )\n",
    "})\n",
    "\n",
    "plt.figure(figsize=(10, 6))\n",
    "plt.hist(diff_df['spectral_centroid_diff'], bins=250)\n",
    "plt.xlabel('Spectral Centroid Difference (Positive - Negative)')\n",
    "plt.ylabel('Count')\n",
    "plt.title('Distribution of Spectral Centroid Differences')\n",
    "plt.axvline(x=0, color='r', linestyle='--', alpha=0.5)\n",
    "print(f\"Mean difference: {diff_df['spectral_centroid_diff'].mean():.4f}\")\n",
    "plt.show()\n",
    "\n",
    "print(\"\\nLargest differences:\")\n",
    "print(diff_df.nlargest(5, 'spectral_centroid_diff'))\n",
    "print(\"\\nSmallest differences:\")\n",
    "print(diff_df.nsmallest(5, 'spectral_centroid_diff'))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "s3_ids = base_metas[\"id_x\"].tolist()\n",
    "\n",
    "base_s3_dir = \"s3://suno-data-uploads/studio/uploads\"\n",
    "s3_filepaths = []\n",
    "for s3_id in s3_ids:\n",
    "    filepath = f\"{base_s3_dir}/{s3_id}.mp3\"\n",
    "    s3_filepaths.append(filepath)\n",
    "\n",
    "print(s3_filepaths[0])\n",
    "print(s3_filepaths[1])\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# plot the histogram of the spectral centroid\n",
    "sc_list = [float(meta[\"features\"][\"spectral_centroid\"]) for meta in ap_metas]\n",
    "sc_list = [sc for sc in sc_list if np.isfinite(sc)]\n",
    "print(len(sc_list))\n",
    "plt.hist(sc_list, bins=1000)\n",
    "plt.show()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print(np.min(sc_list), np.max(sc_list), np.mean(sc_list), np.median(sc_list))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# get the id of the clip with the max spectral centroid\n",
    "max_sc_id = ap_metas[np.argmax(sc_list)][\"id\"]\n",
    "print(max_sc_id)\n",
    "\n",
    "# get the id of the clip with the min spectral centroid\n",
    "min_sc_id = ap_metas[np.argmin(sc_list)][\"id\"]\n",
    "print(min_sc_id)\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "bass_ratio_list = [float(meta[\"features\"][\"bass_ratio\"]) for meta in ap_metas]\n",
    "bass_ratio_list = [br for br in bass_ratio_list if np.isfinite(br)]\n",
    "\n",
    "high_ratio_list = [float(meta[\"features\"][\"high_ratio\"]) for meta in ap_metas]\n",
    "high_ratio_list = [hr for hr in high_ratio_list if np.isfinite(hr)]\n",
    "\n",
    "# cut out the outliers\n",
    "bass_ratio_list = [br for br in bass_ratio_list if br > -10 and br < 10]\n",
    "high_ratio_list = [hr for hr in high_ratio_list if hr > -10 and hr < 10]\n",
    "\n",
    "print(len(bass_ratio_list))\n",
    "print(np.min(bass_ratio_list), np.max(bass_ratio_list), np.mean(bass_ratio_list), np.median(bass_ratio_list))\n",
    "plt.hist(bass_ratio_list, bins=250)\n",
    "plt.show()\n",
    "\n",
    "plt.hist(high_ratio_list, bins=250)\n",
    "plt.show()\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "plt.figure(figsize=(10, 6))\n",
    "\n",
    "# Use density scatter plot with hexbins\n",
    "plt.hexbin(\n",
    "   diff_df['stereo_diff'][mask], \n",
    "   diff_df['spectral_diff'][mask],\n",
    "   gridsize=50,  # Adjust grid size\n",
    "   #cmap='YlOrRd',  # Color map\n",
    "   #bins='log'  # Logarithmic scale for better contrast\n",
    ")\n",
    "\n",
    "plt.colorbar(label='Count (log)')\n",
    "plt.xlabel(\"Stereo Width Difference (Positive - Negative)\")\n",
    "plt.ylabel(\"Spectral Centroid Difference (Positive - Negative)\")\n",
    "plt.axhline(y=0, color='white', linestyle='--', alpha=0.5)\n",
    "plt.axvline(x=0, color='white', linestyle='--', alpha=0.5)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# histogram of the stereo width\n",
    "stereo_width_list = [float(meta[\"features\"][\"stereo_width\"]) for meta in ap_metas]\n",
    "stereo_width_list = [sw for sw in stereo_width_list if np.isfinite(sw)]\n",
    "plt.hist(stereo_width_list, bins=250)\n",
    "plt.show()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# id of the clip with the max stereo width\n",
    "max_sw_id = ap_metas[np.argmax(stereo_width_list)][\"id\"]\n",
    "print(max_sw_id)\n",
    "\n",
    "# id of the clip with the min stereo width\n",
    "min_sw_id = ap_metas[np.argmin(stereo_width_list)][\"id\"]\n",
    "print(min_sw_id)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "suno_env",
   "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.10.9"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
