{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-09-18T21:29:08.684908Z",
     "iopub.status.busy": "2025-09-18T21:29:08.684786Z",
     "iopub.status.idle": "2025-09-18T21:29:08.698541Z",
     "shell.execute_reply": "2025-09-18T21:29:08.698130Z",
     "shell.execute_reply.started": "2025-09-18T21:29:08.684892Z"
    }
   },
   "outputs": [],
   "source": [
    "# setup autoload\n",
    "%load_ext autoreload\n",
    "%autoreload 2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-16T13:58:21.040680Z",
     "start_time": "2024-05-16T13:58:19.777010Z"
    },
    "execution": {
     "iopub.execute_input": "2025-09-18T21:29:08.701846Z",
     "iopub.status.busy": "2025-09-18T21:29:08.701550Z",
     "iopub.status.idle": "2025-09-18T21:29:11.346820Z",
     "shell.execute_reply": "2025-09-18T21:29:11.346265Z",
     "shell.execute_reply.started": "2025-09-18T21:29:08.701832Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The autoreload extension is already loaded. To reload it, use:\n",
      "  %reload_ext autoreload\n"
     ]
    }
   ],
   "source": [
    "import ast\n",
    "import os\n",
    "import shutil\n",
    "import sys\n",
    "from collections import defaultdict\n",
    "\n",
    "import json\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "from preference_data_preparation_auk import *\n",
    "from preference_helper import *\n",
    "from sklearn.model_selection import train_test_split\n",
    "from suno_utils.utils.s3 import download_s3_files\n",
    "from suno_utils.utils.text import read_json, read_jsonl, write_json, write_jsonl\n",
    "from tqdm import tqdm\n",
    "\n",
    "pd.set_option(\"display.max_rows\", 500)\n",
    "pd.set_option(\"display.max_columns\", 500)\n",
    "pd.set_option(\"display.width\", 1000)\n",
    "\n",
    "# setup autoload\n",
    "%load_ext autoreload\n",
    "%autoreload 2\n",
    "\n",
    "\n",
    "def custom_parse(x):\n",
    "    try:\n",
    "        return json.loads(x)\n",
    "    except:\n",
    "        return {}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-16T13:58:21.082172Z",
     "start_time": "2024-05-16T13:58:21.041926Z"
    },
    "execution": {
     "iopub.execute_input": "2025-09-18T21:29:11.349177Z",
     "iopub.status.busy": "2025-09-18T21:29:11.349040Z",
     "iopub.status.idle": "2025-09-18T21:29:11.414432Z",
     "shell.execute_reply": "2025-09-18T21:29:11.413944Z",
     "shell.execute_reply.started": "2025-09-18T21:29:11.349161Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "N_TOKENS_AUDIO 12000\n"
     ]
    }
   ],
   "source": [
    "OUT_DATA_DIR = \"/app2/suno/data/dpo/bluejay_t1_v63\"\n",
    "os.makedirs(OUT_DATA_DIR, exist_ok=True)\n",
    "shutil.copyfile(\n",
    "    \"/app/suno/data/dpo/7v_v20_full/tokenizer_60k.json\",\n",
    "    os.path.join(OUT_DATA_DIR, \"tokenizer_60k.json\"),\n",
    ")\n",
    "NPZ_DIR = \"/app2/suno/data/dpo/bluejay_t1_npz\"\n",
    "N_TOKENS_AUDIO = 25 * 8 * 60\n",
    "print(\"N_TOKENS_AUDIO\", N_TOKENS_AUDIO)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-09-18T21:29:11.416196Z",
     "iopub.status.busy": "2025-09-18T21:29:11.416050Z",
     "iopub.status.idle": "2025-09-18T21:32:28.165236Z",
     "shell.execute_reply": "2025-09-18T21:32:28.164594Z",
     "shell.execute_reply.started": "2025-09-18T21:29:11.416182Z"
    }
   },
   "outputs": [],
   "source": [
    "df = pd.read_pickle(\n",
    "    \"/home/tony/Data/Preference/bluejay_t1/interesting_clips_bluejay_t1_20250918.pkl\"\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-09-18T21:32:28.167324Z",
     "iopub.status.busy": "2025-09-18T21:32:28.167194Z",
     "iopub.status.idle": "2025-09-18T21:32:41.245400Z",
     "shell.execute_reply": "2025-09-18T21:32:41.244734Z",
     "shell.execute_reply.started": "2025-09-18T21:32:28.167309Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "after dropna (8767942, 86)\n"
     ]
    }
   ],
   "source": [
    "df = df.dropna(axis=1, how=\"all\")\n",
    "print(\"after dropna\", df.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-16T13:58:56.199480Z",
     "start_time": "2024-05-16T13:58:53.963687Z"
    },
    "execution": {
     "iopub.execute_input": "2025-09-18T21:32:41.247552Z",
     "iopub.status.busy": "2025-09-18T21:32:41.247414Z",
     "iopub.status.idle": "2025-09-18T21:38:51.241746Z",
     "shell.execute_reply": "2025-09-18T21:38:51.241141Z",
     "shell.execute_reply.started": "2025-09-18T21:32:41.247536Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "12845500\n",
      "12845500\n",
      "pre-downloaded df (8767942, 86)\n",
      "downloaded df (8767942, 86)\n"
     ]
    }
   ],
   "source": [
    "converted_paths = os.listdir(NPZ_DIR)\n",
    "print(len(converted_paths))\n",
    "\n",
    "converted_paths = set([f.replace(\".npz\", \"\") for f in converted_paths])\n",
    "print(len(converted_paths))\n",
    "\n",
    "print(\"pre-downloaded df\", df.shape)\n",
    "df[df[\"s3_id\"].isin(converted_paths)].shape\n",
    "df = df[df[\"s3_id\"].isin(converted_paths)].copy()\n",
    "print(\"downloaded df\", df.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-16T13:58:56.467253Z",
     "start_time": "2024-05-16T13:58:56.207647Z"
    },
    "execution": {
     "iopub.execute_input": "2025-09-18T21:38:51.242512Z",
     "iopub.status.busy": "2025-09-18T21:38:51.242356Z",
     "iopub.status.idle": "2025-09-18T21:38:52.577828Z",
     "shell.execute_reply": "2025-09-18T21:38:52.577211Z",
     "shell.execute_reply.started": "2025-09-18T21:38:51.242497Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "task\n",
       "                      5324160\n",
       "cover                 2079496\n",
       "artist_consistency     600910\n",
       "artist_cover           327572\n",
       "extend                 147274\n",
       "playlist_condition     104696\n",
       "upload_extend           78166\n",
       "infill                  35178\n",
       "overpainting            32812\n",
       "artist_extend           24296\n",
       "underpainting           13382\n",
       "Name: count, dtype: int64"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df[\"task\"].value_counts()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# LET's do the data prep"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-16T13:58:56.592883Z",
     "start_time": "2024-05-16T13:58:56.470781Z"
    },
    "execution": {
     "iopub.execute_input": "2025-09-18T21:38:52.578633Z",
     "iopub.status.busy": "2025-09-18T21:38:52.578464Z",
     "iopub.status.idle": "2025-09-18T21:38:58.304370Z",
     "shell.execute_reply": "2025-09-18T21:38:58.303761Z",
     "shell.execute_reply.started": "2025-09-18T21:38:52.578617Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "preference  model_name      \n",
      "False       chirp-bluejay-t2    4383971\n",
      "True        chirp-bluejay-t2    4383971\n",
      "Name: count, dtype: int64\n",
      "before filter on model name (8767942, 86)\n",
      "after filter on model name (8767942, 86)\n",
      "is_public\n",
      "False    8285971\n",
      "True      481971\n",
      "Name: count, dtype: int64\n"
     ]
    }
   ],
   "source": [
    "## for 13b this is easy for now\n",
    "print(df.groupby([\"preference\"])[\"model_name\"].value_counts())\n",
    "print(\"before filter on model name\", df.shape)\n",
    "df = df[df[\"model_name\"].isin([\"chirp-bluejay-t1\", \"chirp-bluejay-t2\"])]\n",
    "# df = df[df[\"model_name\"].isin([\"chirp-v3p5-engine-t-6\"])]\n",
    "print(\"after filter on model name\", df.shape)\n",
    "print(df[\"is_public\"].value_counts())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-16T13:58:56.909539Z",
     "start_time": "2024-05-16T13:58:56.595736Z"
    },
    "execution": {
     "iopub.execute_input": "2025-09-18T21:38:58.305140Z",
     "iopub.status.busy": "2025-09-18T21:38:58.304983Z",
     "iopub.status.idle": "2025-09-18T21:39:14.746890Z",
     "shell.execute_reply": "2025-09-18T21:39:14.746254Z",
     "shell.execute_reply.started": "2025-09-18T21:38:58.305124Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "before filter on request id pairs (8767942, 86)\n",
      "after filter on request id pairs (8767942, 86)\n",
      "preference  model_name      \n",
      "False       chirp-bluejay-t2    4383971\n",
      "True        chirp-bluejay-t2    4383971\n",
      "Name: count, dtype: int64\n"
     ]
    }
   ],
   "source": [
    "print(\"before filter on request id pairs\", df.shape)\n",
    "df = df[\n",
    "    df[\"request_id\"].isin(\n",
    "        df[\"request_id\"].value_counts().index[df[\"request_id\"].value_counts() == 2]\n",
    "    )\n",
    "]\n",
    "print(\"after filter on request id pairs\", df.shape)\n",
    "print(df.groupby([\"preference\"])[\"model_name\"].value_counts())\n",
    "assert df.shape[0] == df[\"request_id\"].nunique() * 2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-09-18T21:39:14.747709Z",
     "iopub.status.busy": "2025-09-18T21:39:14.747551Z",
     "iopub.status.idle": "2025-09-18T22:05:51.064859Z",
     "shell.execute_reply": "2025-09-18T22:05:51.064092Z",
     "shell.execute_reply.started": "2025-09-18T21:39:14.747693Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "unique_requests 4383971\n",
      "before removing duplicates (8767942, 198)\n",
      "after removing duplicates (8767942, 191)\n"
     ]
    }
   ],
   "source": [
    "# Let's use the old selection for now -- for quality assurance\n",
    "# expand the metadata columns -- this takes forever...~ 6 mins\n",
    "# test_slice = df[\"metadata\"].apply(lambda x: ast.literal_eval(str(x)))\n",
    "# test_slice = df[\"metadata\"].apply(lambda x: custom_parse(x))\n",
    "test_slice = df[\"metadata\"]  # .apply(lambda x: custom_parse(x))\n",
    "test_slice_series = test_slice.apply(pd.Series)\n",
    "df = pd.concat([df, test_slice_series], axis=1, join=\"inner\")\n",
    "print(\"unique_requests\", df[\"request_id\"].nunique())\n",
    "# remove the duplicates\n",
    "print(\"before removing duplicates\", df.shape)\n",
    "df = df.loc[:, ~df.columns.duplicated()].copy()\n",
    "print(\"after removing duplicates\", df.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-09-18T22:05:51.065915Z",
     "iopub.status.busy": "2025-09-18T22:05:51.065619Z",
     "iopub.status.idle": "2025-09-18T22:06:16.850817Z",
     "shell.execute_reply": "2025-09-18T22:06:16.850195Z",
     "shell.execute_reply.started": "2025-09-18T22:05:51.065897Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "pos_diff_preference\n",
       "1.0    2941023\n",
       "2.0    1442948\n",
       "Name: count, dtype: int64"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df = df.sort_values(by=[\"request_id\", \"preference\", \"diff_preference\"])\n",
    "df[\"pos_diff_preference\"] = df[\"diff_preference\"].diff()\n",
    "# df[\"cer_diff_preference\"] = df[\"cer\"].diff()\n",
    "df[df[\"preference\"]][\"pos_diff_preference\"].value_counts()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-09-18T22:06:16.851830Z",
     "iopub.status.busy": "2025-09-18T22:06:16.851537Z",
     "iopub.status.idle": "2025-09-18T22:06:24.628866Z",
     "shell.execute_reply": "2025-09-18T22:06:24.628111Z",
     "shell.execute_reply.started": "2025-09-18T22:06:16.851813Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "positive param_experiment\n",
      "mask_control_slider    207919\n",
      "cfg_steps_240           71203\n",
      "cfg_steps_60            70201\n",
      "n_tag_3                 70173\n",
      "temp_s_95               69823\n",
      "n_tag_1                 69793\n",
      "temp_s_85               69414\n",
      "tag_cfg_05              69193\n",
      "temp_s_80               69044\n",
      "cfg_steps_10            68792\n",
      "tag_cfg_20              68347\n",
      "Name: count, dtype: int64\n"
     ]
    }
   ],
   "source": [
    "try:\n",
    "    print(\"positive\", df[df[\"preference\"]][\"param_experiment\"].value_counts())\n",
    "except:\n",
    "    pass"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-09-18T22:06:24.629888Z",
     "iopub.status.busy": "2025-09-18T22:06:24.629614Z",
     "iopub.status.idle": "2025-09-18T22:08:31.210608Z",
     "shell.execute_reply": "2025-09-18T22:08:31.209880Z",
     "shell.execute_reply.started": "2025-09-18T22:06:24.629871Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Found 576022 duplicated prompts 288011 unique requests\n",
      "Found 153963 request_ids with duplicate prompts but not highest play counts in their group\n",
      "['5da026c4-3736-4243-8a23-c3b44e079853', 'be457373-b1d7-43c8-bd01-17e07623b775', '3457d50f-d5a6-40e0-99fe-036b4068952d', '81bc7d09-a4df-4486-9b06-871094eb3637', 'a4cda31e-3ac3-4318-82db-59afe10f90f9', 'e133f663-b418-4861-8c23-0e33546632a5', 'edcdb55c-95b2-4ed4-b556-bb445fd314dc', 'faf6c004-90cb-46c0-8a02-fb5726dd4355', '0be30ee8-fcb6-4f33-98fd-81bc2d5d040f', '15c757b0-2ef3-48d7-ac29-adb46769ca59']\n",
      "Before dedup user gen requests 8767942\n",
      "After dedup user gen requests 8767942\n"
     ]
    }
   ],
   "source": [
    "# Find duplicated prompts with count > 2\n",
    "duplicate_entries = df.groupby(\n",
    "    [\"user_id\", \"prompt_text\", \"tags\", \"task\", \"edited_clip_id\"]\n",
    ").filter(lambda x: len(x) > 2)\n",
    "print(\n",
    "    \"Found\",\n",
    "    len(duplicate_entries),\n",
    "    \"duplicated prompts\",\n",
    "    len(duplicate_entries[\"request_id\"].unique()),\n",
    "    \"unique requests\",\n",
    ")\n",
    "\n",
    "# Group by user_id, prompt_text, and tags to find duplicate prompt groups\n",
    "prompt_groups = duplicate_entries.groupby(\n",
    "    [\"user_id\", \"prompt_text\", \"tags\", \"task\", \"edited_clip_id\"]\n",
    ")\n",
    "\n",
    "# For each prompt group, find the request_id with the highest total reaction_play_count\n",
    "low_play_count_request_ids = []\n",
    "for prompt_key, prompt_group in prompt_groups:\n",
    "    # Get the sum of reaction_play_count for each request_id in this group\n",
    "    request_play_counts = prompt_group.groupby(\"request_id\")[\n",
    "        \"reaction_play_count\"\n",
    "    ].sum()\n",
    "\n",
    "    # Find the max play count in this group\n",
    "    max_play_count = request_play_counts.max()\n",
    "\n",
    "    # Add request_ids that don't have the max play count to our filter list\n",
    "    lower_play_count_request_ids = request_play_counts[\n",
    "        request_play_counts < max_play_count\n",
    "    ].index.tolist()\n",
    "    low_play_count_request_ids.extend(lower_play_count_request_ids)\n",
    "\n",
    "# Display the filtered request IDs\n",
    "print(\n",
    "    f\"Found {len(low_play_count_request_ids)} request_ids with duplicate prompts but not highest play counts in their group\"\n",
    ")\n",
    "print(\n",
    "    low_play_count_request_ids[:10]\n",
    "    if len(low_play_count_request_ids) > 10\n",
    "    else low_play_count_request_ids\n",
    ")\n",
    "print(\"Before dedup user gen requests\", df.shape[0])\n",
    "# df = df[~df[\"request_id\"].isin(low_play_count_request_ids)]\n",
    "print(\"After dedup user gen requests\", df.shape[0])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-16T13:59:40.799375Z",
     "start_time": "2024-05-16T13:59:36.394236Z"
    },
    "execution": {
     "iopub.execute_input": "2025-09-18T22:08:31.211486Z",
     "iopub.status.busy": "2025-09-18T22:08:31.211322Z",
     "iopub.status.idle": "2025-09-18T22:09:25.971047Z",
     "shell.execute_reply": "2025-09-18T22:09:25.970299Z",
     "shell.execute_reply.started": "2025-09-18T22:08:31.211469Z"
    },
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "114176\n",
      "good_continue_at\n",
      "True     8755610\n",
      "False      12332\n",
      "Name: count, dtype: int64\n",
      "\n",
      " Check some basics... \n",
      " preference\n",
      "False    4383971\n",
      "True     4383971\n",
      "Name: count, dtype: int64 model_name\n",
      "chirp-bluejay-t2    8767942\n",
      "Name: count, dtype: int64 preference  model_name      \n",
      "False       chirp-bluejay-t2    4383971\n",
      "True        chirp-bluejay-t2    4383971\n",
      "Name: count, dtype: int64\n",
      "task\n",
      "                      5324160\n",
      "cover                 2079496\n",
      "artist_consistency     600910\n",
      "artist_cover           327572\n",
      "extend                 147274\n",
      "playlist_condition     104696\n",
      "upload_extend           78166\n",
      "infill                  35178\n",
      "overpainting            32812\n",
      "artist_extend           24296\n",
      "underpainting           13382\n",
      "Name: count, dtype: int64\n"
     ]
    }
   ],
   "source": [
    "df[\"id\"] = df[\"str_id\"]\n",
    "# get the original duration of the clips, if they are concacted\n",
    "df[\"original_duration_s\"] = df[\"total_start_s\"] + df[\"duration\"]\n",
    "# classify the continue at behavoirs by the duration choice\n",
    "audio_prompt_id_to_continue_at = {}\n",
    "\n",
    "for _, row in df[~df[\"continued_parent\"].isna()].iterrows():\n",
    "    audio_prompt_id = row[\"continued_parent\"]\n",
    "    if audio_prompt_id not in audio_prompt_id_to_continue_at:\n",
    "        audio_prompt_id_to_continue_at[audio_prompt_id] = row[\"continue_at\"]\n",
    "    else:\n",
    "        # pick the max\n",
    "        audio_prompt_id = max(\n",
    "            audio_prompt_id_to_continue_at[audio_prompt_id], row[\"continue_at\"]\n",
    "        )\n",
    "print(len(audio_prompt_id_to_continue_at))\n",
    "df[\"has_continue_and_start_continue_at\"] = df[\"id\"].apply(\n",
    "    lambda x: audio_prompt_id_to_continue_at.get(x)\n",
    ")\n",
    "# we want continue at to be at most of the clip...\n",
    "df[\"good_continue_at\"] = (\n",
    "    (df[\"has_continue_and_start_continue_at\"] / df[\"duration\"]) > 0.9\n",
    ") | df[\"has_continue_and_start_continue_at\"].isna()\n",
    "print(df[\"good_continue_at\"].value_counts())\n",
    "\n",
    "\n",
    "print(\n",
    "    \"\\n Check some basics... \\n\",\n",
    "    df[\"preference\"].value_counts(),\n",
    "    df[\"model_name\"].value_counts(),\n",
    "    df.groupby([\"preference\"])[\"model_name\"].value_counts(),\n",
    ")\n",
    "\n",
    "df = df.sort_values(by=[\"request_id\", \"preference\"])\n",
    "df[\"duration_rel_diff\"] = df[\"duration\"].diff()\n",
    "df[\"play_rel_diff\"] = df[\"reaction_play_count\"].diff()\n",
    "print(df[\"task\"].value_counts())\n",
    "\n",
    "df[\"post_infill_duration\"] = (\n",
    "    df[\"duration\"]\n",
    "    + df[\"infill_context_end_s\"]\n",
    "    - df[\"infill_context_start_s\"]\n",
    "    - df[\"include_future_s\"]\n",
    "    - df[\"include_history_s\"]\n",
    "    - df[\"infill_dur_s\"]\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-16T13:59:41.035167Z",
     "start_time": "2024-05-16T13:59:40.801098Z"
    },
    "execution": {
     "iopub.execute_input": "2025-09-18T22:09:25.972204Z",
     "iopub.status.busy": "2025-09-18T22:09:25.971930Z",
     "iopub.status.idle": "2025-09-18T22:10:01.731115Z",
     "shell.execute_reply": "2025-09-18T22:10:01.730339Z",
     "shell.execute_reply.started": "2025-09-18T22:09:25.972186Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "after duration 0.9993251552074591\n",
      "after infill duration 0.999885720046962\n",
      "neg_filter_reaction_play_count 1.0\n",
      "neg_filter_upvote_count 0.9902\n",
      "neg_filter_norm_play_frac 1.0\n",
      "neg_filter_continues 1.0\n",
      "----------------\n",
      "pos_filter_continues 0.9972\n",
      "pos_filter_reaction_play_count 1.0\n",
      "pos_filter_relative_play_count 0.9789\n",
      "pos_filter_cer_diff_preference 1.0\n",
      "pos_filter_bad_flags 0.9998\n",
      "after filter on play counts 0.9818\n",
      "after filter on higher quality 0.3414\n",
      "----------------\n",
      "negative 4337197 positive 1390582\n",
      "----------------\n",
      "total pair requests 4383971  --> selected pair requests 1375963 frac 0.314  --> total intitial users 453775\n"
     ]
    }
   ],
   "source": [
    "normal_pos_play_count = 3\n",
    "# this is lower, cause a concat is probably already ensuring that it is good\n",
    "concat_pos_play_count = 1\n",
    "# this is a filter on the concated clip\n",
    "concat_total_play_count = 3\n",
    "\n",
    "all_fitlers = (df[\"duration\"] >= 10) & (df[\"duration\"] <= 480)\n",
    "print(\"after duration\", all_fitlers.sum() / df.shape[0])\n",
    "infill_duration_filter = ~df[\"task\"].isin(\n",
    "    [\n",
    "        \"infill\",\n",
    "        \"infill_intro\",\n",
    "        \"infill_outro\",\n",
    "    ]\n",
    ")  | (df[\"post_infill_duration\"] <= 239)\n",
    "print(\"after infill duration\", infill_duration_filter.sum() / df.shape[0])\n",
    "# negative fitlers\n",
    "total_negative = df[~df[\"preference\"]].shape[0]\n",
    "neg_filter_reaction_play_count = (~df[\"preference\"]) & (df[\"reaction_play_count\"] >= 1)\n",
    "print(\n",
    "    \"neg_filter_reaction_play_count\",\n",
    "    round(neg_filter_reaction_play_count.sum() / total_negative, 4),\n",
    ")\n",
    "neg_filter_upvote_count = (~df[\"preference\"]) & (df[\"upvote_count\"] == 0)\n",
    "print(\n",
    "    \"neg_filter_upvote_count\",\n",
    "    round(neg_filter_upvote_count.sum() / total_negative, 4),\n",
    ")\n",
    "neg_filter_norm_play_frac = (~df[\"preference\"]) & (df[\"norm_play_frac\"] <= 3.1)\n",
    "print(\n",
    "    \"neg_filter_norm_play_frac\",\n",
    "    round(neg_filter_norm_play_frac.sum() / total_negative, 4),\n",
    ")\n",
    "neg_filter_continues = (~df[\"preference\"]) & (\n",
    "    df[\"has_continue_and_start_continue_at\"].isna()\n",
    ")\n",
    "print(\n",
    "    \"neg_filter_continues\",\n",
    "    round(neg_filter_continues.sum() / total_negative, 4),\n",
    ")\n",
    "\n",
    "neg_filter_selection_mask = (\n",
    "    all_fitlers\n",
    "    & infill_duration_filter\n",
    "    & neg_filter_reaction_play_count\n",
    "    & neg_filter_upvote_count\n",
    "    & neg_filter_norm_play_frac\n",
    "    & neg_filter_continues\n",
    ")\n",
    "\n",
    "print(\"----------------\")\n",
    "total_positive = df[df[\"preference\"]].shape[0]\n",
    "assert total_positive == total_negative\n",
    "pos_filter_continues = (df[\"preference\"]) & (df[\"good_continue_at\"])\n",
    "print(\"pos_filter_continues\", round(pos_filter_continues.sum() / total_positive, 4))\n",
    "pos_filter_reaction_play_count = (df[\"preference\"]) & (df[\"reaction_play_count\"] >= 1)\n",
    "print(\n",
    "    \"pos_filter_reaction_play_count\",\n",
    "    round(pos_filter_reaction_play_count.sum() / total_positive, 4),\n",
    ")\n",
    "pos_filter_relative_play_count = (df[\"preference\"]) & (df[\"play_rel_diff\"] >= 0)\n",
    "print(\n",
    "    \"pos_filter_relative_play_count\",\n",
    "    round(pos_filter_relative_play_count.sum() / total_positive, 4),\n",
    ")\n",
    "pos_filter_cer_diff_preference = (\n",
    "    df[\n",
    "        \"preference\"\n",
    "    ]  # & (df[\"pos_diff_preference\"] == 2) # & (df[\"cer_diff_preference\"] < 0.5) & (df[\"cer\"] < 0.99)\n",
    ")\n",
    "print(\n",
    "    \"pos_filter_cer_diff_preference\",\n",
    "    round(pos_filter_cer_diff_preference.sum() / total_positive, 4),\n",
    ")\n",
    "pos_filter_bad_flags = (\n",
    "    (df[\"preference\"]) & (df[\"flag_count\"] == 0) & (df[\"dislike_count\"] == 0)\n",
    ")\n",
    "print(\n",
    "    \"pos_filter_bad_flags\",\n",
    "    round(pos_filter_bad_flags.sum() / total_positive, 4),\n",
    ")\n",
    "pos_filter_play_counts = (df[\"preference\"]) & (\n",
    "    (\n",
    "        (df[\"part_of_concat\"])\n",
    "        & (df[\"reaction_play_count\"] >= concat_pos_play_count)\n",
    "        & (df[\"concat_play_counts\"] >= concat_total_play_count)\n",
    "    )\n",
    "    | (\n",
    "        (~df[\"part_of_concat\"]) & (df[\"reaction_play_count\"] >= normal_pos_play_count)\n",
    "        # & (df[\"norm_play_frac\"] >= 2.1)  # this is a bit of a luxury cut...\n",
    "    )\n",
    "    | (df[\"task\"].isin([\"infill\", \"infill_intro\", \"infill_outro\"]))\n",
    ")\n",
    "print(\n",
    "    \"after filter on play counts\",\n",
    "    round(pos_filter_play_counts.sum() / total_positive, 4),\n",
    ")\n",
    "high_quality_tasks_filter = (\n",
    "    (\n",
    "        df[\"task\"].isin(\n",
    "            [\n",
    "                \"cover\",\n",
    "                \"upload_extend\",\n",
    "                \"cover_extend\",\n",
    "                \"artist_cover\",\n",
    "                \"extend\",\n",
    "                \"artist_consistency\",\n",
    "                \"artist_extend\",\n",
    "                \"playlist_condition\",\n",
    "                \"\",\n",
    "            ]\n",
    "        )\n",
    "    )\n",
    "    & (\n",
    "        (df[\"upvote_count\"] >= 1)  # (df[\"upvote_count\"] >= 1)\n",
    "        | (df[\"reaction_play_count\"] >= 5)\n",
    "        | (df[\"concat_play_counts\"] >= 5)\n",
    "    )\n",
    "    & (\n",
    "        (df[\"part_of_concat\"])\n",
    "        | (\n",
    "            (~df[\"part_of_concat\"])\n",
    "            & (df[\"norm_play_frac\"] >= 5.1)  # this is a bit of a luxury cut...\n",
    "            & (\n",
    "                df[\"norm_play_frac\"] >= df[\"reaction_play_count\"] / 3\n",
    "            )  # play duration is not low on average\n",
    "        )\n",
    "    )\n",
    ")\n",
    "medium_quality_tasks_filter = (\n",
    "    df[\"task\"].isin(\n",
    "        [\n",
    "            \"infill\",\n",
    "            \"infill_intro\",\n",
    "            \"infill_outro\",\n",
    "            \"overpainting\",\n",
    "            \"underpainting\",\n",
    "        ]\n",
    "    )\n",
    ") & (  # let more infill through only in this case...\n",
    "    (\n",
    "        df[\"upvote_count\"] >= 1\n",
    "    )  # (df[\"upvote_count\"] >= 1)  (df[\"pos_diff_preference\"] == 2)\n",
    "    | (df[\"reaction_play_count\"] >= 1)\n",
    "    | (df[\"concat_play_counts\"] >= 1)\n",
    ")\n",
    "pos_filter_higher_quality = (df[\"preference\"]) & (\n",
    "    high_quality_tasks_filter | medium_quality_tasks_filter\n",
    ")\n",
    "print(\n",
    "    \"after filter on higher quality\",\n",
    "    round(pos_filter_higher_quality.sum() / total_positive, 4),\n",
    ")\n",
    "\n",
    "user_gen_filter = (\n",
    "    df[\"user_n_clips\"] >= 20\n",
    ")  # user needs to have genereated at least 100 over the time period\n",
    "\n",
    "print(\"----------------\")\n",
    "pos_filter_selectin_mask = (\n",
    "    (df[\"preference\"])  # get basics aligned\n",
    "    & all_fitlers\n",
    "    & infill_duration_filter\n",
    "    & pos_filter_continues\n",
    "    & pos_filter_reaction_play_count\n",
    "    & pos_filter_relative_play_count\n",
    "    & pos_filter_cer_diff_preference\n",
    "    & pos_filter_bad_flags\n",
    "    & pos_filter_play_counts\n",
    "    & pos_filter_higher_quality\n",
    "    & user_gen_filter\n",
    ")\n",
    "print(\n",
    "    \"negative\",\n",
    "    sum(neg_filter_selection_mask),\n",
    "    \"positive\",\n",
    "    sum(pos_filter_selectin_mask),\n",
    ")\n",
    "\n",
    "neg_filter_requests = df[neg_filter_selection_mask][\"request_id\"].unique()\n",
    "pos_filter_requests = df[pos_filter_selectin_mask][\"request_id\"].unique()\n",
    "# looking for very strong signal here:\n",
    "# listen to the positive/negative more than once\n",
    "# disliked one of the clips\n",
    "unique_requests = set(pos_filter_requests).intersection(neg_filter_requests)\n",
    "print(\"----------------\")\n",
    "print(\n",
    "    \"total pair requests\",\n",
    "    df[\"request_id\"].nunique(),\n",
    "    \" --> selected pair requests\",\n",
    "    len(unique_requests),\n",
    "    f\"frac {len(unique_requests) / df['request_id'].nunique():.3f}\",\n",
    "    \" --> total intitial users\",\n",
    "    df[\"user_id\"].nunique(),\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-16T13:59:41.250737Z",
     "start_time": "2024-05-16T13:59:41.036434Z"
    },
    "execution": {
     "iopub.execute_input": "2025-09-18T22:10:01.732284Z",
     "iopub.status.busy": "2025-09-18T22:10:01.732017Z",
     "iopub.status.idle": "2025-09-18T22:10:17.753780Z",
     "shell.execute_reply": "2025-09-18T22:10:17.753016Z",
     "shell.execute_reply.started": "2025-09-18T22:10:01.732267Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "task\n",
      "                      1708576\n",
      "cover                  540614\n",
      "artist_consistency     196104\n",
      "artist_cover            93542\n",
      "extend                  75032\n",
      "playlist_condition      32316\n",
      "infill                  30810\n",
      "overpainting            30408\n",
      "upload_extend           19222\n",
      "artist_extend           12986\n",
      "underpainting           12316\n",
      "Name: count, dtype: int64\n",
      "bluejay_t1_v63 requests 1375963 clips 2751926 total khrs 155.384; N gpus for 1000 iters 171.995; 4 gpus for x iters 42998.844; n unique users 268809 n pro users 240816\n"
     ]
    }
   ],
   "source": [
    "df_slice = df[df[\"request_id\"].isin(set(unique_requests))].copy()\n",
    "print(df_slice[\"task\"].value_counts())\n",
    "print(\n",
    "    f\"{os.path.basename(OUT_DATA_DIR)} requests\",\n",
    "    df_slice[\"request_id\"].nunique(),\n",
    "    \"clips\",\n",
    "    df_slice.shape[0],\n",
    "    f\"total khrs {sum(df_slice['duration'] / 3600 / 1000):.3f};\",\n",
    "    f\"N gpus for 1000 iters {df_slice.shape[0] / 8 / 2 / 1000:.3f};\",\n",
    "    f\"4 gpus for x iters {df_slice.shape[0] / 8 / 2 / 4:.3f};\",\n",
    "    f\"n unique users {df_slice['user_id'].nunique()}\",\n",
    "    f\"n pro users {df_slice[df_slice['is_pro_user']]['user_id'].nunique()}\",\n",
    ")\n",
    "# auk_mix_t1_v2 requests 102002 clips 204004 total khrs 9.191; N gpus for 1000 iters 12.750; 4 gpus for x iters 3187.562; n unique users 36408 n pro users 34038\n",
    "# auk_t1_v1 requests 9179 clips 18358 total khrs 0.854; N gpus for 1000 iters 1.147; 4 gpus for x iters 286.844; n unique users 6288 n pro users 6275\n",
    "# auk_t1_v2 requests 40903 clips 81806 total khrs 3.864; N gpus for 1000 iters 5.113; 4 gpus for x iters 1278.219; n unique users 21079 n pro users 20966\n",
    "# auk_t1_v3 requests 102015 clips 204030 total khrs 9.703; N gpus for 1000 iters 12.752; 4 gpus for x iters 3187.969; n unique users 42837 n pro users 42462\n",
    "# auk_t1_v4 requests 211452 clips 422904 total khrs 20.216; N gpus for 1000 iters 26.431; 4 gpus for x iters 6607.875; n unique users 71182 n pro users 70059\n",
    "# auk_t1_v9 requests 547743 clips 1095486 total khrs 56.567; N gpus for 1000 iters 68.468; 4 gpus for x iters 17116.969; n unique users 129354 n pro users 125126\n",
    "# auk_t1_v13 requests 627646 clips 1255292 total khrs 64.530; N gpus for 1000 iters 78.456; 4 gpus for x iters 19613.938; n unique users 139873 n pro users 134738\n",
    "# auk_t1_v17 requests 494902 clips 989804 total khrs 51.445; N gpus for 1000 iters 61.863; 4 gpus for x iters 15465.688; n unique users 114240 n pro users 109708\n",
    "# auk_t1_v19 requests 740881 clips 1481762 total khrs 76.133; N gpus for 1000 iters 92.610; 4 gpus for x iters 23152.531; n unique users 154570 n pro users 147261\n",
    "# auk_t1_v24 requests 717745 clips 1435490 total khrs 74.515; N gpus for 1000 iters 89.718; 4 gpus for x iters 22429.531; n unique users 139344 n pro users 130740\n",
    "# auk_t1_v29 requests 1097586 clips 2195172 total khrs 112.614; N gpus for 1000 iters 137.198; 4 gpus for x iters 34299.562; n unique users 193138 n pro users 179429\n",
    "# auk_t1_v30 requests 1224422 clips 2448844 total khrs 125.330; N gpus for 1000 iters 153.053; 4 gpus for x iters 38263.188; n unique users 203138 n pro users 186758\n",
    "# auk_t1_v31 requests 389265 clips 778530 total khrs 40.761; N gpus for 1000 iters 48.658; 4 gpus for x iters 12164.531; n unique users 85198 n pro users 78445\n",
    "# auk_t1_v33 requests 1285261 clips 2570522 total khrs 131.585; N gpus for 1000 iters 160.658; 4 gpus for x iters 40164.406; n unique users 208932 n pro users 191380\n",
    "# auk_t1_v33 requests 1086639 clips 2173278 total khrs 110.641; N gpus for 1000 iters 135.830; 4 gpus for x iters 33957.469; n unique users 197293 n pro users 180968 -- play dur from /3 to /2\n",
    "# auk_t1_v33 requests 806877 clips 1613754 total khrs 81.964; N gpus for 1000 iters 100.860; 4 gpus for x iters 25214.906; n unique users 156679 n pro users 144253 -- filter to web\n",
    "# auk_t1_v37 requests 1339132 clips 2678264 total khrs 137.055; N gpus for 1000 iters 167.392; 4 gpus for x iters 41847.875; n unique users 214313 n pro users 196815\n",
    "# auk_t1_v38 requests 979451 clips 1958902 total khrs 102.038; N gpus for 1000 iters 122.431; 4 gpus for x iters 30607.844; n unique users 170773 n pro users 156737\n",
    "# auk_t1_v43 requests 184775 clips 369550 total khrs 19.089; N gpus for 1000 iters 23.097; 4 gpus for x iters 5774.219; n unique users 60652 n pro users 59126\n",
    "# auk_t1_v45 requests 1176216 clips 2352432 total khrs 122.102; N gpus for 1000 iters 147.027; 4 gpus for x iters 36756.750; n unique users 176751 n pro users 163097\n",
    "# auk_t1_v48 requests 294407 clips 588814 total khrs 29.992; N gpus for 1000 iters 36.801; 4 gpus for x iters 9200.219; n unique users 80991 n pro users 78825\n",
    "# bluejay_t1_v1 requests 47405 clips 94810 total khrs 5.515; N gpus for 1000 iters 5.926; 4 gpus for x iters 1481.406; n unique users 24344 n pro users 24194\n",
    "# bluejay_t1_v2 requests 101265 clips 202530 total khrs 11.753; N gpus for 1000 iters 12.658; 4 gpus for x iters 3164.531; n unique users 44574 n pro users 44024\n",
    "# bluejay_t1_v3 requests 144765 clips 289530 total khrs 16.756; N gpus for 1000 iters 18.096; 4 gpus for x iters 4523.906; n unique users 58421 n pro users 57449\n",
    "# bluejay_t1_v5 requests 179289 clips 358578 total khrs 20.764; N gpus for 1000 iters 22.411; 4 gpus for x iters 5602.781; n unique users 67850 n pro users 66572\n",
    "# bluejay_t1_v7 requests 282305 clips 564610 total khrs 32.692; N gpus for 1000 iters 35.288; 4 gpus for x iters 8822.031; n unique users 93023 n pro users 90936\n",
    "# bluejay_t1_v9 requests 540570 clips 1081140 total khrs 62.455; N gpus for 1000 iters 67.571; 4 gpus for x iters 16892.812; n unique users 145720 n pro users 142027\n",
    "# bluejay_t1_v11 requests 184433 clips 368866 total khrs 20.955; N gpus for 1000 iters 23.054; 4 gpus for x iters 5763.531; n unique users 52149 n pro users 51402\n",
    "# bluejay_t1_v12 requests 293821 clips 587642 total khrs 33.820; N gpus for 1000 iters 36.728; 4 gpus for x iters 9181.906; n unique users 98138 n pro users 95838\n",
    "# bluejay_t1_v13 requests 355678 clips 711356 total khrs 40.908; N gpus for 1000 iters 44.460; 4 gpus for x iters 11114.938; n unique users 111544 n pro users 108497\n",
    "# bluejay_t1_v17 requests 415411 clips 830822 total khrs 48.043; N gpus for 1000 iters 51.926; 4 gpus for x iters 12981.594; n unique users 124572 n pro users 120683\n",
    "# bluejay_t1_v24 requests 486884 clips 973768 total khrs 56.292; N gpus for 1000 iters 60.861; 4 gpus for x iters 15215.125; n unique users 138727 n pro users 133829\n",
    "# bluejay_t1_v26 requests 336220 clips 672440 total khrs 38.800; N gpus for 1000 iters 42.028; 4 gpus for x iters 10506.875; n unique users 80832 n pro users 78854\n",
    "# bluejay_t1_v28 requests 683709 clips 1367418 total khrs 78.507; N gpus for 1000 iters 85.464; 4 gpus for x iters 21365.906; n unique users 172776 n pro users 164584\n",
    "# bluejay_t1_v28 requests 662650 clips 1325300 total khrs 76.539; N gpus for 1000 iters 82.831; 4 gpus for x iters 20707.812; n unique users 170192 n pro users 162222\n",
    "# bluejay_t1_v31 requests 855246 clips 1710492 total khrs 97.846; N gpus for 1000 iters 106.906; 4 gpus for x iters 26726.438; n unique users 198438 n pro users 186068\n",
    "# bluejay_t1_v31 requests 829339 clips 1658678 total khrs 95.430; N gpus for 1000 iters 103.667; 4 gpus for x iters 25916.844; n unique users 195575 n pro users 183523\n",
    "# bluejay_t1_v31 requests 932058 clips 1864116 total khrs 107.136; N gpus for 1000 iters 116.507; 4 gpus for x iters 29126.812; n unique users 203738 n pro users 190639\n",
    "# bluejay_t1_v41 requests 1122075 clips 2244150 total khrs 128.936; N gpus for 1000 iters 140.259; 4 gpus for x iters 35064.844; n unique users 232511 n pro users 214225\n",
    "# bluejay_t1_v42 requests 1234273 clips 2468546 total khrs 140.767; N gpus for 1000 iters 154.284; 4 gpus for x iters 38571.031; n unique users 246967 n pro users 226020"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-09-18T22:10:17.754654Z",
     "iopub.status.busy": "2025-09-18T22:10:17.754491Z",
     "iopub.status.idle": "2025-09-18T22:10:17.770755Z",
     "shell.execute_reply": "2025-09-18T22:10:17.770212Z",
     "shell.execute_reply.started": "2025-09-18T22:10:17.754638Z"
    }
   },
   "outputs": [],
   "source": [
    "# import time\n",
    "# time.sleep(3600)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-09-18T22:10:17.771467Z",
     "iopub.status.busy": "2025-09-18T22:10:17.771319Z",
     "iopub.status.idle": "2025-09-18T22:16:34.765520Z",
     "shell.execute_reply": "2025-09-18T22:16:34.764785Z",
     "shell.execute_reply.started": "2025-09-18T22:10:17.771452Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Total hoot cer scores: 3687062\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      " 88%|███████████████████████████████████████████████████████████████████████████████████████████▎            | 182657/207912 [05:15<00:44, 571.75it/s]IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n"
     ]
    }
   ],
   "source": [
    "# Load existing hoot CER cache\n",
    "with open(\"/home/tony/Data/Preference/bluejay_t1/hoot_cer.json\", \"r\") as file:\n",
    "    clip_id_to_cer = json.load(file)\n",
    "print(\"Total hoot cer scores:\", len(clip_id_to_cer))\n",
    "\n",
    "JSON_DIR = \"/app2/suno/data/dpo/bluejay_t1_json/\"\n",
    "\n",
    "# Extract unique s3_ids from df_slice that are not already in the cache\n",
    "clip_ids = set(df_slice[\"s3_id\"]) - set(clip_id_to_cer.keys())\n",
    "\n",
    "for clip_id in tqdm(clip_ids):\n",
    "    hoot_json_path = os.path.join(JSON_DIR, f\"{clip_id}_hoot.json\")\n",
    "    if not os.path.exists(hoot_json_path):\n",
    "        clip_id_to_cer[clip_id] = 1.0\n",
    "        continue\n",
    "    with open(hoot_json_path, \"r\") as f:\n",
    "        data = json.load(f)\n",
    "    for data_dict in data:\n",
    "        if \"hoot_cer\" in data_dict:\n",
    "            clip_id_to_cer[clip_id] = data_dict[\"hoot_cer\"]\n",
    "            break\n",
    "\n",
    "# Update the hoot CER cache\n",
    "with open(\"/home/tony/Data/Preference/bluejay_t1/hoot_cer.json\", \"w\") as file:\n",
    "    json.dump(clip_id_to_cer, file)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-09-18T22:16:34.766814Z",
     "iopub.status.busy": "2025-09-18T22:16:34.766266Z",
     "iopub.status.idle": "2025-09-18T22:17:08.491821Z",
     "shell.execute_reply": "2025-09-18T22:17:08.491053Z",
     "shell.execute_reply.started": "2025-09-18T22:16:34.766794Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "count    1.375963e+06\n",
      "mean    -3.526318e-03\n",
      "std      1.208061e-01\n",
      "min     -1.000000e+00\n",
      "10%     -8.760286e-02\n",
      "50%      0.000000e+00\n",
      "90%      7.510288e-02\n",
      "95%      1.463627e-01\n",
      "96%      1.724553e-01\n",
      "97%      2.102182e-01\n",
      "98%      2.738443e-01\n",
      "99%      4.053340e-01\n",
      "max      1.000000e+00\n",
      "Name: cer_diff, dtype: float64\n",
      "bluejay_t1_v63 requests 1352279 clips 2704558 total khrs 153.240; N gpus for 1000 iters 169.035; 4 gpus for x iters 42258.719; n unique users 266796 n pro users 239102\n"
     ]
    }
   ],
   "source": [
    "# # add the cer to the df\n",
    "df_slice[\"cer\"] = df_slice[\"s3_id\"].map(clip_id_to_cer)\n",
    "df_slice = df_slice.fillna({\"cer\": 1})\n",
    "df_slice[\"cer_diff\"] = df_slice[\"cer\"].diff()\n",
    "df_slice = df_slice.fillna({\"cer_diff\": 0})\n",
    "print(df_slice[df_slice[\"preference\"]][\"cer_diff\"].describe(percentiles=[0.1, 0.5, 0.9, 0.95, 0.96, 0.97, 0.98, 0.99]))\n",
    "\n",
    "# just trimming off tail is fine and safe. Used to be 0.2. Multiple rounds now so probably 0.3 is still fine.\n",
    "cer_mask = (df_slice[\"preference\"]) & (df_slice[\"cer_diff\"] < 0.3)\n",
    "pos_cer_filter_requests = df_slice[cer_mask][\"request_id\"].unique()\n",
    "df_slice = df_slice[df_slice[\"request_id\"].isin(set(pos_cer_filter_requests))].copy()\n",
    "print(\n",
    "    f\"{os.path.basename(OUT_DATA_DIR)} requests\",\n",
    "    df_slice[\"request_id\"].nunique(),\n",
    "    \"clips\",\n",
    "    df_slice.shape[0],\n",
    "    f\"total khrs {sum(df_slice['duration'] / 3600 / 1000):.3f};\",\n",
    "    f\"N gpus for 1000 iters {df_slice.shape[0] / 8 / 2 / 1000:.3f};\",\n",
    "    f\"4 gpus for x iters {df_slice.shape[0] / 8 / 2 / 4:.3f};\",\n",
    "    f\"n unique users {df_slice['user_id'].nunique()}\",\n",
    "    f\"n pro users {df_slice[df_slice['is_pro_user']]['user_id'].nunique()}\",\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-09-18T22:17:08.492719Z",
     "iopub.status.busy": "2025-09-18T22:17:08.492544Z",
     "iopub.status.idle": "2025-09-18T22:17:09.004271Z",
     "shell.execute_reply": "2025-09-18T22:17:09.003689Z",
     "shell.execute_reply.started": "2025-09-18T22:17:08.492702Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "source\n",
       "web        2019910\n",
       "android     381222\n",
       "ios         303426\n",
       "Name: count, dtype: int64"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df_slice[\"source\"].value_counts()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-16T13:59:41.277006Z",
     "start_time": "2024-05-16T13:59:41.252105Z"
    },
    "execution": {
     "iopub.execute_input": "2025-09-18T22:17:09.005106Z",
     "iopub.status.busy": "2025-09-18T22:17:09.004945Z",
     "iopub.status.idle": "2025-09-18T22:17:10.092463Z",
     "shell.execute_reply": "2025-09-18T22:17:10.091752Z",
     "shell.execute_reply.started": "2025-09-18T22:17:09.005090Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "positive in playlist (412259, 200)\n",
      "task\n",
      "                      1675366\n",
      "cover                  534404\n",
      "artist_consistency     193648\n",
      "artist_cover            92556\n",
      "extend                  73396\n",
      "playlist_condition      31804\n",
      "infill                  30074\n",
      "overpainting            29598\n",
      "upload_extend           18712\n",
      "artist_extend           12742\n",
      "underpainting           12258\n",
      "Name: count, dtype: int64\n"
     ]
    }
   ],
   "source": [
    "test_mask = (df_slice[\"preference\"]) & (\n",
    "    (df_slice[\"is_in_playlist\"]) | (df_slice[\"concat_in_playlist\"])\n",
    ")\n",
    "print(\"positive in playlist\", df_slice[test_mask].shape)\n",
    "print(df_slice[\"task\"].value_counts())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-09-18T22:17:10.093335Z",
     "iopub.status.busy": "2025-09-18T22:17:10.093170Z",
     "iopub.status.idle": "2025-09-18T22:17:10.118926Z",
     "shell.execute_reply": "2025-09-18T22:17:10.118311Z",
     "shell.execute_reply.started": "2025-09-18T22:17:10.093319Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "is_public\n",
      "False    2466917\n",
      "True      237641\n",
      "Name: count, dtype: int64\n"
     ]
    }
   ],
   "source": [
    "print(df_slice[\"is_public\"].value_counts())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-09-18T22:17:10.119722Z",
     "iopub.status.busy": "2025-09-18T22:17:10.119567Z",
     "iopub.status.idle": "2025-09-18T22:17:10.688415Z",
     "shell.execute_reply": "2025-09-18T22:17:10.687752Z",
     "shell.execute_reply.started": "2025-09-18T22:17:10.119707Z"
    }
   },
   "outputs": [],
   "source": [
    "df_slice[\"npz_path\"] = df_slice[\"s3_id\"].map(lambda x: f\"{NPZ_DIR}/{x}.npz\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-09-18T22:17:10.689252Z",
     "iopub.status.busy": "2025-09-18T22:17:10.689089Z",
     "iopub.status.idle": "2025-09-18T22:17:20.560340Z",
     "shell.execute_reply": "2025-09-18T22:17:20.559588Z",
     "shell.execute_reply.started": "2025-09-18T22:17:10.689237Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(2704558, 201)\n"
     ]
    }
   ],
   "source": [
    "df_total = df_slice.copy()\n",
    "print(df_total.shape)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## SOME SNOWFLAKE LYRICS SHIT YOU DON\"T WNAT TO KNOW"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-09-18T22:17:20.565327Z",
     "iopub.status.busy": "2025-09-18T22:17:20.564682Z",
     "iopub.status.idle": "2025-09-18T22:17:23.909498Z",
     "shell.execute_reply": "2025-09-18T22:17:23.908812Z",
     "shell.execute_reply.started": "2025-09-18T22:17:20.565306Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "PROD\n"
     ]
    }
   ],
   "source": [
    "home_dir = os.path.expanduser(\"~\")\n",
    "snow_password_path = os.path.join(home_dir, \".aws\", \"snow_pw.txt\")\n",
    "if os.path.exists(snow_password_path):\n",
    "    # !pip install snowflake\n",
    "    from snowflake.core import Root\n",
    "    from snowflake.snowpark import Session\n",
    "\n",
    "    with open(snow_password_path, \"r\") as fp:\n",
    "        fp_lines = fp.readlines()\n",
    "        snow_password = fp_lines[0].strip()\n",
    "        snow_username = fp_lines[1].strip()\n",
    "\n",
    "    CONNECTION_PARAMETERS = {\n",
    "        \"account\": \"fu90569.us-east-2.aws\",\n",
    "        \"user\": snow_username,\n",
    "        \"private_key_file\": \"/home/tony/.aws/rsa_key.p8\",\n",
    "        \"role\": \"ACCOUNTADMIN\",\n",
    "        \"database\": \"SUNO_PROD\",\n",
    "        \"warehouse\": \"SUNO_PROD_LARGE\",\n",
    "        \"schema\": \"PROD\",\n",
    "    }\n",
    "\n",
    "if not os.path.exists(snow_password_path):\n",
    "    raise Exception(\"you are not authorized to access snowflake -- please setup\")\n",
    "\n",
    "snow_session = Session.builder.configs(CONNECTION_PARAMETERS).create()\n",
    "\n",
    "snow_root = Root(snow_session)\n",
    "snow_schema = snow_root.databases[\"SUNO_PROD\"].schemas[\"PROD\"]\n",
    "print(snow_schema.name)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-09-18T22:17:23.910356Z",
     "iopub.status.busy": "2025-09-18T22:17:23.910196Z",
     "iopub.status.idle": "2025-09-18T22:19:42.528754Z",
     "shell.execute_reply": "2025-09-18T22:19:42.528155Z",
     "shell.execute_reply.started": "2025-09-18T22:17:23.910340Z"
    }
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "  0%|                                                                                                                           | 0/1 [00:00<?, ?it/s]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Number of new clip IDs in this chunk: 60768\n",
      "Length of the ID query string: 2369951\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [01:00<00:00, 60.73s/it]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Number of new result batches: 1\n",
      "Shape of df_snow_prompt:\n",
      "Rows: 3610434\n",
      "Columns: 2\n",
      "False    2557186\n",
      "True      147372\n",
      "Name: count, dtype: int64\n"
     ]
    }
   ],
   "source": [
    "import os\n",
    "import pandas as pd\n",
    "import pickle\n",
    "from tqdm import tqdm\n",
    "from typing import List\n",
    "\n",
    "PROMPT_PATH = \"/home/tony/Data/Preference/bluejay_t1/clip_prompt.pkl\"\n",
    "\n",
    "# Load existing prompts if available\n",
    "df_existing_prompts = pd.read_pickle(PROMPT_PATH)\n",
    "df_existing_prompts[\"id\"] = df_existing_prompts[\"id\"].astype(str)\n",
    "\n",
    "df_total[\"id\"] = df_total[\"id\"].astype(str)\n",
    "# Only query for new clip ids not already in the prompt cache\n",
    "existing_ids = set(df_existing_prompts[\"id\"])\n",
    "all_clip_ids = set(df_total[\"id\"].unique())\n",
    "new_clip_ids = list(all_clip_ids - existing_ids)\n",
    "\n",
    "snow_batch_size = 100_000\n",
    "snow_results: List[pd.DataFrame] = []\n",
    "\n",
    "if new_clip_ids:\n",
    "    for clip_ids_chunk in tqdm(\n",
    "        [new_clip_ids[i : i + snow_batch_size] for i in range(0, len(new_clip_ids), snow_batch_size)]\n",
    "    ):\n",
    "        id_query_str = \",\".join(\"'\" + x + \"'\" for x in clip_ids_chunk)\n",
    "        print(f\"Number of new clip IDs in this chunk: {len(clip_ids_chunk)}\")\n",
    "        print(f\"Length of the ID query string: {len(id_query_str)}\")\n",
    "\n",
    "        session_query = snow_session.sql(\n",
    "            f\"\"\"select ID, PROMPT_TEXT\n",
    "            from DDB_CLIP_META_HEAVY\n",
    "            where ID in ({id_query_str})\n",
    "            order by p_hour desc;\"\"\"\n",
    "        )\n",
    "        temp_df_snow = pd.DataFrame(session_query.collect())\n",
    "        snow_results.append(temp_df_snow)\n",
    "    print(f\"Number of new result batches: {len(snow_results)}\")\n",
    "    df_snow_new = pd.concat(snow_results, ignore_index=True)\n",
    "    df_snow_new = df_snow_new.rename(columns=lambda x: x.lower())\n",
    "    # Combine with existing prompts and drop duplicates (keep latest)\n",
    "    df_snow_prompt = pd.concat([df_existing_prompts, df_snow_new], ignore_index=True)\n",
    "    df_snow_prompt = df_snow_prompt.drop_duplicates(subset=[\"id\"], keep=\"last\")\n",
    "else:\n",
    "    print(\"No new clip IDs to query.\")\n",
    "    df_snow_prompt = df_existing_prompts\n",
    "\n",
    "# Save the updated prompt DataFrame every time\n",
    "df_snow_prompt.to_pickle(PROMPT_PATH)\n",
    "\n",
    "print(\"Shape of df_snow_prompt:\")\n",
    "print(f\"Rows: {df_snow_prompt.shape[0]}\")\n",
    "print(f\"Columns: {df_snow_prompt.shape[1]}\")\n",
    "\n",
    "df_total = df_total.rename(columns={'prompt_text': 'prompt_text_old'})\n",
    "df_total = df_total.merge(df_snow_prompt, on=\"id\", how=\"left\")\n",
    "print((df_total[\"prompt_text\"] == df_total[\"prompt_text_old\"]).value_counts())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Fetch inference parameters"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-09-18T22:19:42.529527Z",
     "iopub.status.busy": "2025-09-18T22:19:42.529372Z",
     "iopub.status.idle": "2025-09-18T22:24:21.098133Z",
     "shell.execute_reply": "2025-09-18T22:24:21.097440Z",
     "shell.execute_reply.started": "2025-09-18T22:19:42.529512Z"
    }
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "2025-09-18 22:20:28,335 - INFO - Found credentials in shared credentials file: ~/.aws/credentials\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "missing 60720\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "2025-09-18 22:20:29,672 - INFO - Starting parallel query for 10000 UUIDs with 50 workers\n",
      "Querying DynamoDB: 100%|███████████████████████████████████████████████████████████████████████████████████████| 10000/10000 [00:16<00:00, 596.32it/s]\n",
      "2025-09-18 22:20:46,444 - INFO - Retrieved 20000 total records from DynamoDB\n",
      "2025-09-18 22:20:46,472 - INFO - Found credentials in shared credentials file: ~/.aws/credentials\n",
      "2025-09-18 22:20:46,837 - INFO - Starting parallel query for 10000 UUIDs with 50 workers\n",
      "Querying DynamoDB: 100%|███████████████████████████████████████████████████████████████████████████████████████| 10000/10000 [00:17<00:00, 581.51it/s]\n",
      "2025-09-18 22:21:04,035 - INFO - Retrieved 20000 total records from DynamoDB\n",
      "2025-09-18 22:21:04,065 - INFO - Found credentials in shared credentials file: ~/.aws/credentials\n",
      "2025-09-18 22:21:04,425 - INFO - Starting parallel query for 10000 UUIDs with 50 workers\n",
      "Querying DynamoDB: 100%|███████████████████████████████████████████████████████████████████████████████████████| 10000/10000 [00:18<00:00, 551.40it/s]\n",
      "2025-09-18 22:21:22,562 - INFO - Retrieved 20000 total records from DynamoDB\n",
      "2025-09-18 22:21:22,588 - INFO - Found credentials in shared credentials file: ~/.aws/credentials\n",
      "2025-09-18 22:21:22,939 - INFO - Starting parallel query for 10000 UUIDs with 50 workers\n",
      "Querying DynamoDB: 100%|███████████████████████████████████████████████████████████████████████████████████████| 10000/10000 [00:17<00:00, 574.52it/s]\n",
      "2025-09-18 22:21:40,346 - INFO - Retrieved 20000 total records from DynamoDB\n",
      "2025-09-18 22:21:40,377 - INFO - Found credentials in shared credentials file: ~/.aws/credentials\n",
      "2025-09-18 22:21:41,230 - INFO - Starting parallel query for 10000 UUIDs with 50 workers\n",
      "Querying DynamoDB: 100%|███████████████████████████████████████████████████████████████████████████████████████| 10000/10000 [00:19<00:00, 525.23it/s]\n",
      "2025-09-18 22:22:00,271 - INFO - Retrieved 20000 total records from DynamoDB\n",
      "2025-09-18 22:22:00,311 - INFO - Found credentials in shared credentials file: ~/.aws/credentials\n",
      "2025-09-18 22:22:00,678 - INFO - Starting parallel query for 10000 UUIDs with 50 workers\n",
      "Querying DynamoDB: 100%|███████████████████████████████████████████████████████████████████████████████████████| 10000/10000 [01:00<00:00, 164.29it/s]\n",
      "2025-09-18 22:23:01,546 - INFO - Retrieved 20000 total records from DynamoDB\n",
      "2025-09-18 22:23:01,591 - INFO - Found credentials in shared credentials file: ~/.aws/credentials\n",
      "2025-09-18 22:23:02,692 - INFO - Starting parallel query for 720 UUIDs with 50 workers\n",
      "Querying DynamoDB: 100%|███████████████████████████████████████████████████████████████████████████████████████████| 720/720 [00:02<00:00, 248.94it/s]\n",
      "2025-09-18 22:23:05,586 - INFO - Retrieved 1440 total records from DynamoDB\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(3695812, 70)\n"
     ]
    }
   ],
   "source": [
    "import os\n",
    "import pandas as pd\n",
    "from fetch_gen_config import query_dynamodb_by_uuids_optimized\n",
    "\n",
    "DYNAMO_PATH = \"/home/tony/Data/Preference/bluejay_t1/clip_dynamo.pkl\"\n",
    "\n",
    "# Load existing DynamoDB records if available\n",
    "if os.path.exists(DYNAMO_PATH):\n",
    "    df_dynamo = pd.read_pickle(DYNAMO_PATH)\n",
    "    existing_ids = set(df_dynamo[\"clipId\"].tolist())\n",
    "else:\n",
    "    df_dynamo = pd.DataFrame()\n",
    "    existing_ids = set()\n",
    "\n",
    "total_s3_ids = set(df_total[\"id\"].tolist())\n",
    "missing_ids = list(total_s3_ids - existing_ids)\n",
    "print(\"missing\", len(missing_ids))\n",
    "chunk_size = 10_000\n",
    "all_records = []\n",
    "\n",
    "for i in range(0, len(missing_ids), chunk_size):\n",
    "    chunk = missing_ids[i:i + chunk_size]\n",
    "    try:\n",
    "        records = query_dynamodb_by_uuids_optimized(chunk, profile_name=\"default\")\n",
    "        all_records.extend(records)\n",
    "    except Exception as e:\n",
    "        # Log and continue with next chunk\n",
    "        print(f\"Error querying DynamoDB for chunk {i // chunk_size}: {e}\")\n",
    "\n",
    "if all_records:\n",
    "    df_new = pd.DataFrame(all_records)\n",
    "    df_dynamo = pd.concat([df_dynamo, df_new], ignore_index=True)\n",
    "\n",
    "print(df_dynamo.shape)\n",
    "df_dynamo[df_dynamo[\"type\"] == \"gpt\"].to_pickle(DYNAMO_PATH)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-09-18T22:24:21.099116Z",
     "iopub.status.busy": "2025-09-18T22:24:21.098838Z",
     "iopub.status.idle": "2025-09-18T22:24:22.429775Z",
     "shell.execute_reply": "2025-09-18T22:24:22.429200Z",
     "shell.execute_reply.started": "2025-09-18T22:24:21.099099Z"
    }
   },
   "outputs": [],
   "source": [
    "# df_total.to_pickle(\"/home/tony/Data/Preference/bluejay_t1/interesting_clips_bluejay_t1_20250817_subset_total.pkl\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-09-19T00:57:58.992664Z",
     "iopub.status.busy": "2025-09-19T00:57:58.992284Z",
     "iopub.status.idle": "2025-09-19T00:57:59.074167Z",
     "shell.execute_reply": "2025-09-19T00:57:59.073559Z",
     "shell.execute_reply.started": "2025-09-19T00:57:58.992645Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "N_TOKENS_AUDIO 12000\n"
     ]
    }
   ],
   "source": [
    "OUT_DATA_DIR = \"/app2/suno/data/dpo/bluejay_t1_v63\"\n",
    "os.makedirs(OUT_DATA_DIR, exist_ok=True)\n",
    "shutil.copyfile(\n",
    "    \"/app/suno/data/dpo/7v_v20_full/tokenizer_60k.json\",\n",
    "    os.path.join(OUT_DATA_DIR, \"tokenizer_60k.json\"),\n",
    ")\n",
    "NPZ_DIR = \"/app2/suno/data/dpo/bluejay_t1_npz\"\n",
    "N_TOKENS_AUDIO = 25 * 8 * 60\n",
    "print(\"N_TOKENS_AUDIO\", N_TOKENS_AUDIO)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-09-18T22:24:22.510314Z",
     "iopub.status.busy": "2025-09-18T22:24:22.510165Z",
     "iopub.status.idle": "2025-09-18T22:24:28.225596Z",
     "shell.execute_reply": "2025-09-18T22:24:28.224870Z",
     "shell.execute_reply.started": "2025-09-18T22:24:22.510300Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(2704558, 202) (353182, 202)\n",
      "after date cut (353182, 202)\n"
     ]
    }
   ],
   "source": [
    "# # v18 # 07-22\n",
    "# # v19 # 07-26\n",
    "# # v20 # 07-29\n",
    "# # v21 # 08-01\n",
    "# # v22 # 08-04\n",
    "# # v23 # 08-09\n",
    "# # v24 07-30\n",
    "# # v28 # 07-29\n",
    "# # v29 # 08-07\n",
    "# # v30 # \n",
    "# # v32 # 07-22\n",
    "# # v33 # 07-26\n",
    "# # v34 # 07-29\n",
    "# # v35 # 08-04 342386\n",
    "# # v36 # 08-10 337956\n",
    "# # v37 # 08-16 321330\n",
    "# # v39 # 08-16 on 371610\n",
    "# # # \n",
    "# # v42 # 07-22 170036\n",
    "# # v43 # 07-26 181850\n",
    "# # v44 # 07-29 176956\n",
    "# # v45 # 08-04 360168\n",
    "# # v46 # 08-10 360288\n",
    "# # v47 # 08-16 351520\n",
    "# # v48 # 08-22 351814\n",
    "# # v49 # 08-29 366208\n",
    "# # v50 \n",
    "# # v59 # 08-29 349396\n",
    "# # v60 # 09-05 354426\n",
    "# # v61 # 09-12 335234\n",
    "# # v62 # rest and everything\n",
    "df_total[\"created_at\"] = pd.to_datetime(df_total[\"created_at\"], utc=True)\n",
    "start_cutoff_date = pd.to_datetime(\"2025-09-05\", utc=True)\n",
    "end_cutoff_date = pd.to_datetime(\"2025-09-12\", utc=True)\n",
    "date_mask = (df_total[\"created_at\"] < end_cutoff_date) & (df_total[\"created_at\"] >= start_cutoff_date)\n",
    "print(df_total.shape, df_total[date_mask].shape)\n",
    "df_slice = df_total[date_mask].copy()\n",
    "print(\"after date cut\", df_slice.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-09-19T00:41:26.236227Z",
     "iopub.status.busy": "2025-09-19T00:41:26.235856Z",
     "iopub.status.idle": "2025-09-19T00:41:40.676901Z",
     "shell.execute_reply": "2025-09-19T00:41:40.676195Z",
     "shell.execute_reply.started": "2025-09-19T00:41:26.236208Z"
    }
   },
   "outputs": [],
   "source": [
    "df_slice = df_total.copy()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-09-19T00:41:40.678184Z",
     "iopub.status.busy": "2025-09-19T00:41:40.677908Z",
     "iopub.status.idle": "2025-09-19T00:42:36.267414Z",
     "shell.execute_reply": "2025-09-19T00:42:36.266692Z",
     "shell.execute_reply.started": "2025-09-19T00:41:40.678167Z"
    }
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Collecting known train IDs:  10%|████████▌                                                                             | 1/10 [00:02<00:25,  2.82s/it]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Added 168330 new IDs from /app2/suno/data/dpo/bluejay_t1_v42 (total: 168330)\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Collecting known train IDs:  20%|█████████████████▏                                                                    | 2/10 [00:05<00:24,  3.03s/it]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Added 180030 new IDs from /app2/suno/data/dpo/bluejay_t1_v43 (total: 348360)\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Collecting known train IDs:  30%|█████████████████████████▊                                                            | 3/10 [00:09<00:21,  3.02s/it]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Added 175186 new IDs from /app2/suno/data/dpo/bluejay_t1_v44 (total: 523546)\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Collecting known train IDs:  40%|██████████████████████████████████▍                                                   | 4/10 [00:15<00:25,  4.27s/it]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Added 356564 new IDs from /app2/suno/data/dpo/bluejay_t1_v45 (total: 880110)\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Collecting known train IDs:  50%|███████████████████████████████████████████                                           | 5/10 [00:21<00:25,  5.01s/it]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Added 356684 new IDs from /app2/suno/data/dpo/bluejay_t1_v46 (total: 1236794)\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Collecting known train IDs:  60%|███████████████████████████████████████████████████▌                                  | 6/10 [00:27<00:21,  5.26s/it]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Added 347998 new IDs from /app2/suno/data/dpo/bluejay_t1_v47 (total: 1584792)\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Collecting known train IDs:  70%|████████████████████████████████████████████████████████████▏                         | 7/10 [00:32<00:16,  5.40s/it]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Added 348294 new IDs from /app2/suno/data/dpo/bluejay_t1_v48 (total: 1933086)\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Collecting known train IDs:  80%|████████████████████████████████████████████████████████████████████▊                 | 8/10 [00:38<00:10,  5.49s/it]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Added 345902 new IDs from /app2/suno/data/dpo/bluejay_t1_v59 (total: 2278988)\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Collecting known train IDs:  90%|█████████████████████████████████████████████████████████████████████████████▍        | 9/10 [00:44<00:05,  5.60s/it]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Added 350880 new IDs from /app2/suno/data/dpo/bluejay_t1_v60 (total: 2629868)\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Collecting known train IDs: 100%|█████████████████████████████████████████████████████████████████████████████████████| 10/10 [00:49<00:00,  4.99s/it]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Added 331880 new IDs from /app2/suno/data/dpo/bluejay_t1_v61 (total: 2961748)\n",
      "Total known train IDs: 2961748\n",
      "Original df_slice shape: (2704558, 202)\n",
      "Filtered df_slice shape: (522404, 202)\n"
     ]
    }
   ],
   "source": [
    "from tqdm import tqdm\n",
    "\n",
    "list_of_past_data = [\n",
    "    \"/app2/suno/data/dpo/bluejay_t1_v42\",\n",
    "    \"/app2/suno/data/dpo/bluejay_t1_v43\",\n",
    "    \"/app2/suno/data/dpo/bluejay_t1_v44\",\n",
    "    \"/app2/suno/data/dpo/bluejay_t1_v45\",\n",
    "    \"/app2/suno/data/dpo/bluejay_t1_v46\",\n",
    "    \"/app2/suno/data/dpo/bluejay_t1_v47\",\n",
    "    \"/app2/suno/data/dpo/bluejay_t1_v48\",\n",
    "    \"/app2/suno/data/dpo/bluejay_t1_v59\",\n",
    "    \"/app2/suno/data/dpo/bluejay_t1_v60\",\n",
    "    \"/app2/suno/data/dpo/bluejay_t1_v61\",\n",
    "]\n",
    "\n",
    "# Collect all known train IDs from previous meta_tr.jsonl files, showing progress and set growth\n",
    "known_train_ids = set()\n",
    "for data_dir in tqdm(list_of_past_data, desc=\"Collecting known train IDs\"):\n",
    "    metas = read_jsonl(os.path.join(data_dir, \"meta_tr.jsonl\"))\n",
    "    before = len(known_train_ids)\n",
    "    known_train_ids.update(meta[\"id\"] for meta in metas)\n",
    "    after = len(known_train_ids)\n",
    "    tqdm.write(f\"Added {after - before} new IDs from {data_dir} (total: {after})\")\n",
    "\n",
    "print(f\"Total known train IDs: {len(known_train_ids)}\")\n",
    "print(f\"Original df_slice shape: {df_slice.shape}\")\n",
    "df_slice = df_slice[~df_slice[\"id\"].isin(known_train_ids)].copy()\n",
    "print(f\"Filtered df_slice shape: {df_slice.shape}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-09-19T00:42:36.268402Z",
     "iopub.status.busy": "2025-09-19T00:42:36.268244Z",
     "iopub.status.idle": "2025-09-19T00:42:37.457955Z",
     "shell.execute_reply": "2025-09-19T00:42:37.457385Z",
     "shell.execute_reply.started": "2025-09-19T00:42:36.268387Z"
    }
   },
   "outputs": [],
   "source": [
    "# from collections import Counter, defaultdict\n",
    "# from typing import List, Dict, Set\n",
    "\n",
    "# # Read all meta files\n",
    "# meta_files: List[str] = [\n",
    "#     \"/app/suno/data/dpo/30b_t1_v23/meta_tr.jsonl\",\n",
    "#     \"/app/suno/data/dpo/30b_t6_v35/meta_tr.jsonl\",\n",
    "#     \"/app/suno/data/dpo/13b_s32_v34/meta_tr.jsonl\",\n",
    "#     \"/app/suno/data/dpo/auk_mix_t1_v6/meta_tr.jsonl\",\n",
    "#     \"/app/suno/data/dpo/auk_mix_t1_v14/meta_tr.jsonl\",\n",
    "#     \"/app2/suno/data/dpo/auk_t1_v6/meta_tr.jsonl\",\n",
    "#     \"/app2/suno/data/dpo/auk_t1_v7/meta_tr.jsonl\",\n",
    "#     \"/app2/suno/data/dpo/auk_t1_v19/meta_tr.jsonl\",\n",
    "#     \"/app2/suno/data/dpo/auk_t1_v29/meta_tr.jsonl\",\n",
    "# ]\n",
    "\n",
    "# user_id_counter: Counter[str] = Counter()\n",
    "# for meta_file in tqdm(meta_files):\n",
    "#     metas = read_jsonl(meta_file)\n",
    "#     # Count each user_id once per dataset\n",
    "#     user_ids: Set[str] = {meta[\"user_id\"] for meta in metas if \"user_id\" in meta}\n",
    "#     user_id_counter.update(user_ids)\n",
    "\n",
    "# # Map from count to set of user_ids\n",
    "# count_to_users: Dict[int, Set[str]] = defaultdict(set)\n",
    "# for user_id, count in user_id_counter.items():\n",
    "#     count_to_users[count].add(user_id)\n",
    "\n",
    "# for count in sorted(count_to_users):\n",
    "#     users = count_to_users[count]\n",
    "#     print(f\"Count {count}: {len(users)} users\")\n",
    "\n",
    "# # with open(\"/home/tony/Data/top_user_8.json\", \"w\") as fp:\n",
    "# #     json.dump(list(count_to_users[8]) , fp)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-09-19T00:42:37.459398Z",
     "iopub.status.busy": "2025-09-19T00:42:37.459076Z",
     "iopub.status.idle": "2025-09-19T00:42:37.478101Z",
     "shell.execute_reply": "2025-09-19T00:42:37.477579Z",
     "shell.execute_reply.started": "2025-09-19T00:42:37.459382Z"
    }
   },
   "outputs": [],
   "source": [
    "# with open(\"/home/tony/Data/top_user/mask_control_low.json\", \"r\") as fp:\n",
    "#     very_good_users = json.load(fp)\n",
    "# # very_good_users = count_to_users[5]\n",
    "# very_good_users_mask = df_total[\"user_id\"].isin(very_good_users)\n",
    "# print(df_total[very_good_users_mask].shape, df_total.shape)\n",
    "# print(df_total[very_good_users_mask][\"user_id\"].nunique(), df_total[\"user_id\"].nunique())\n",
    "# # df_total[very_good_users_mask][\"task\"].value_counts()\n",
    "# df_slice = df_total[very_good_users_mask].copy()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-09-19T00:42:37.479027Z",
     "iopub.status.busy": "2025-09-19T00:42:37.478735Z",
     "iopub.status.idle": "2025-09-19T00:42:37.494503Z",
     "shell.execute_reply": "2025-09-19T00:42:37.493985Z",
     "shell.execute_reply.started": "2025-09-19T00:42:37.479013Z"
    }
   },
   "outputs": [],
   "source": [
    "# print(\n",
    "#     \"Before filtering by user_id and task\",\n",
    "#     df_slice.shape[0],\n",
    "#     \"user_id unique:\",\n",
    "#     df_slice[\"user_id\"].nunique(),\n",
    "# )\n",
    "\n",
    "# # Create a copy to avoid fragmentation warning\n",
    "# df_slice = df_slice.copy()\n",
    "\n",
    "# # Calculate score for each row: reaction_play_count + 5 if preference is True, else 0\n",
    "# score_values = (\n",
    "#     df_slice[\"reaction_play_count\"] + (5 * df_slice[\"upvote_count\"].astype(int))\n",
    "# ) * df_slice[\"preference\"].astype(int)\n",
    "\n",
    "# # Use pd.concat to add the score column efficiently\n",
    "# df_slice = pd.concat(\n",
    "#     [df_slice, pd.DataFrame({\"score\": score_values}, index=df_slice.index)], axis=1\n",
    "# )\n",
    "\n",
    "# # Group by user_id and task, then for each group find the request_id with highest score\n",
    "# best_request_ids = []\n",
    "# for (user_id, task), group in tqdm(\n",
    "#     df_slice.groupby([\"user_id\", \"task\"]), desc=\"Processing user_id and task groups\"\n",
    "# ):\n",
    "#     # Get the request_id with the highest score in this group\n",
    "#     best_request_id = group.loc[group[\"score\"].idxmax(), \"request_id\"]\n",
    "#     best_request_ids.append(best_request_id)\n",
    "\n",
    "# # Filter df_slice to keep only the best request_ids for each user_id, task combination\n",
    "# df_slice = df_slice[df_slice[\"request_id\"].isin(best_request_ids)].copy()\n",
    "\n",
    "# print(\n",
    "#     \"After filtering by user_id and task\",\n",
    "#     df_slice.shape[0],\n",
    "#     \"user_id unique:\",\n",
    "#     df_slice[\"user_id\"].nunique(),\n",
    "# )"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-16T14:00:20.866354Z",
     "start_time": "2024-05-16T14:00:12.443344Z"
    },
    "execution": {
     "iopub.execute_input": "2025-09-19T00:42:37.495344Z",
     "iopub.status.busy": "2025-09-19T00:42:37.495064Z",
     "iopub.status.idle": "2025-09-19T00:42:37.570659Z",
     "shell.execute_reply": "2025-09-19T00:42:37.570003Z",
     "shell.execute_reply.started": "2025-09-19T00:42:37.495328Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(522404, 202)\n",
      "task\n",
      "                      324804\n",
      "cover                 102882\n",
      "artist_consistency     36992\n",
      "artist_cover           18220\n",
      "extend                 13670\n",
      "infill                  6130\n",
      "playlist_condition      5964\n",
      "overpainting            5584\n",
      "upload_extend           3474\n",
      "underpainting           2528\n",
      "artist_extend           2156\n",
      "Name: count, dtype: int64\n"
     ]
    },
    {
     "ename": "NameError",
     "evalue": "name 'BREAK' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mNameError\u001b[0m                                 Traceback (most recent call last)",
      "Cell \u001b[0;32mIn[42], line 6\u001b[0m\n\u001b[1;32m      4\u001b[0m \u001b[38;5;28mprint\u001b[39m(df_slice\u001b[38;5;241m.\u001b[39mshape)\n\u001b[1;32m      5\u001b[0m \u001b[38;5;28mprint\u001b[39m(df_slice[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mtask\u001b[39m\u001b[38;5;124m\"\u001b[39m]\u001b[38;5;241m.\u001b[39mvalue_counts())\n\u001b[0;32m----> 6\u001b[0m \u001b[43mBREAK\u001b[49m\n\u001b[1;32m      7\u001b[0m \u001b[38;5;66;03m# (269282, 199)\u001b[39;00m\n",
      "\u001b[0;31mNameError\u001b[0m: name 'BREAK' is not defined"
     ]
    }
   ],
   "source": [
    "# df_slice.to_pickle(\n",
    "#     \"/home/tony/Data/Preference/30b_v6/interesting_clips_v4_h_t_6_20250426_full_long_slice.pkl\"\n",
    "# )\n",
    "print(df_slice.shape)\n",
    "print(df_slice[\"task\"].value_counts())\n",
    "BREAK\n",
    "# (269282, 199)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Need to kick out the ones has gpt prompt -- these are pairs with different text inputs"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-09-19T00:58:06.893505Z",
     "iopub.status.busy": "2025-09-19T00:58:06.893161Z",
     "iopub.status.idle": "2025-09-19T00:58:09.876308Z",
     "shell.execute_reply": "2025-09-19T00:58:09.875606Z",
     "shell.execute_reply.started": "2025-09-19T00:58:06.893486Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(522404, 202)\n",
      "(522404, 202)\n",
      "(522404, 202)\n"
     ]
    }
   ],
   "source": [
    "print(df_slice.shape)\n",
    "df_slice = df_slice[df_slice[\"request_id\"].apply(lambda x: len(x) > 3)]\n",
    "print(df_slice.shape)\n",
    "# df_slice = df_slice[df_slice[\"is_pro_user\"]].copy()\n",
    "print(df_slice.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-16T13:59:41.932296Z",
     "start_time": "2024-05-16T13:59:41.932287Z"
    },
    "execution": {
     "iopub.execute_input": "2025-09-19T00:58:09.877851Z",
     "iopub.status.busy": "2025-09-19T00:58:09.877344Z",
     "iopub.status.idle": "2025-09-19T00:58:09.925930Z",
     "shell.execute_reply": "2025-09-19T00:58:09.925301Z",
     "shell.execute_reply.started": "2025-09-19T00:58:09.877834Z"
    }
   },
   "outputs": [],
   "source": [
    "# don't have continue at\n",
    "df_slice[\"request_id\"] = df_slice[\"request_id\"].astype(str)\n",
    "# df_slice[\"npz_path\"] = df_slice[\"npz_path\"].apply(lambda x: str(x).replace(\"_npz\", \"_npz/\"))\n",
    "# df_slice[df_slice[\"continue_at\"].isna()][\"request_id\"].nunique(), df_slice[\"request_id\"].nunique()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-16T13:59:41.932966Z",
     "start_time": "2024-05-16T13:59:41.932957Z"
    },
    "execution": {
     "iopub.execute_input": "2025-09-19T00:58:09.926881Z",
     "iopub.status.busy": "2025-09-19T00:58:09.926730Z",
     "iopub.status.idle": "2025-09-19T00:58:10.040888Z",
     "shell.execute_reply": "2025-09-19T00:58:10.040250Z",
     "shell.execute_reply.started": "2025-09-19T00:58:09.926866Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "261202\n"
     ]
    }
   ],
   "source": [
    "final_filtered_requests = df_slice[\"request_id\"].astype(str).unique()\n",
    "# final_filtered_requests = df_slice[df_slice[\"is_pro_user\"]][\"request_id\"].astype(str).unique()\n",
    "print(len(final_filtered_requests))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-16T13:59:41.934277Z",
     "start_time": "2024-05-16T13:59:41.934268Z"
    },
    "execution": {
     "iopub.execute_input": "2025-09-19T00:58:10.041898Z",
     "iopub.status.busy": "2025-09-19T00:58:10.041553Z",
     "iopub.status.idle": "2025-09-19T00:58:16.665151Z",
     "shell.execute_reply": "2025-09-19T00:58:16.664445Z",
     "shell.execute_reply.started": "2025-09-19T00:58:10.041882Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "258589 2613\n",
      "(517178, 202) (5226, 202)\n"
     ]
    }
   ],
   "source": [
    "train_requests, val_requests = train_test_split(\n",
    "    sorted(list(final_filtered_requests)), test_size=0.01, random_state=42\n",
    ")\n",
    "print(len(train_requests), len(val_requests))\n",
    "\n",
    "train_df = df_slice[df_slice[\"request_id\"].astype(str).isin(set(train_requests))].copy()\n",
    "val_df = df_slice[df_slice[\"request_id\"].astype(str).isin(set(val_requests))].copy()\n",
    "train_df = train_df.sort_values(by=[\"request_id\", \"preference\"])\n",
    "train_df = train_df  # .reset_index()\n",
    "val_df = val_df.sort_values(by=[\"request_id\", \"preference\"])\n",
    "val_df = val_df  # .reset_index()\n",
    "train_df = train_df.reset_index(drop=True)\n",
    "val_df = val_df.reset_index(drop=True)\n",
    "print(train_df.shape, val_df.shape)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Actually make"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-16T13:59:41.935620Z",
     "start_time": "2024-05-16T13:59:41.935613Z"
    },
    "execution": {
     "iopub.execute_input": "2025-09-19T00:58:16.666724Z",
     "iopub.status.busy": "2025-09-19T00:58:16.666541Z",
     "iopub.status.idle": "2025-09-19T00:58:35.396227Z",
     "shell.execute_reply": "2025-09-19T00:58:35.395540Z",
     "shell.execute_reply.started": "2025-09-19T00:58:16.666707Z"
    }
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|██████████████████████████████████████████████████████████████████████████████████████████████████████| 517178/517178 [00:18<00:00, 27650.72it/s]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "29,342 hours of 517178 clips, 32.323625 nodes, 673.4088541666666 iters\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    }
   ],
   "source": [
    "total_duration = 0\n",
    "for i, row in tqdm(train_df.iterrows(), total=len(train_df)):\n",
    "    # we need to alternate between preference: neg, pos\n",
    "    # print(i, row)\n",
    "    try:\n",
    "        assert row[\"preference\"] == (i % 2 == 1)\n",
    "        total_duration += row[\"duration\"]\n",
    "    except Exception as E:\n",
    "        print(i, row)\n",
    "        print(E)\n",
    "        raise ValueError()\n",
    "\n",
    "print(\n",
    "    f\"{round(total_duration / 60 / 60):,} hours of {train_df.shape[0]} clips, {train_df.shape[0] / 8 / 2 / 1000} nodes, {train_df.shape[0] / 8 / 6 / 16} iters\"\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-16T13:59:41.936268Z",
     "start_time": "2024-05-16T13:59:41.936260Z"
    },
    "execution": {
     "iopub.execute_input": "2025-09-19T00:58:35.397056Z",
     "iopub.status.busy": "2025-09-19T00:58:35.396894Z",
     "iopub.status.idle": "2025-09-19T00:59:55.600541Z",
     "shell.execute_reply": "2025-09-19T00:59:55.599941Z",
     "shell.execute_reply.started": "2025-09-19T00:58:35.397040Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "t_data_memmap is set to: 12000\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|█████████████████████████████████████████████████████████████████████████████████████████████████████████████| 5226/5226 [01:18<00:00, 66.19it/s]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Total 5226 clips, 0 different prompts, 0 different tags, 0 different negative tags\n",
      "195 hours of False\n",
      "195 hours of True\n",
      "artist_cover: 26.5 hours\n",
      "cover: 106.7 hours\n",
      "gen: 189.5 hours\n",
      "extend: 11.2 hours\n",
      "artist_consistency: 35.6 hours\n",
      "overpainting: 6.1 hours\n",
      "underpainting: 3.1 hours\n",
      "playlist_condition: 7.0 hours\n",
      "infill: 1.3 hours\n",
      "artist_extend: 2.6 hours\n",
      "\n",
      "--- Gender Distribution ---\n",
      "  female: 440 (8.4%)\n",
      "  male: 630 (12.1%)\n",
      "  unspecified: 4,156 (79.5%)\n",
      "\n",
      "--- Negative Tags Usage ---\n",
      "  has_neg_tags: 336 (6.4%)\n",
      "  no_neg_tags: 4,890 (93.6%)\n",
      "\n",
      "--- Control Slider Usage ---\n",
      "  has_control_slider: 1,718 (32.9% of clips)\n",
      "  no_control_slider: 3,508 (67.1% of clips)\n",
      "Done\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    }
   ],
   "source": [
    "make_dataset(\n",
    "    val_df, OUT_DATA_DIR, is_val=True, npz_dir=NPZ_DIR, t_data_memmap=N_TOKENS_AUDIO\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-09-19T00:59:55.601317Z",
     "iopub.status.busy": "2025-09-19T00:59:55.601153Z",
     "iopub.status.idle": "2025-09-19T00:59:56.807164Z",
     "shell.execute_reply": "2025-09-19T00:59:56.806684Z",
     "shell.execute_reply.started": "2025-09-19T00:59:55.601300Z"
    }
   },
   "outputs": [],
   "source": [
    "# test_npz = np.load(\"/app/suno/data/dpo/30b_npz/26d19085-18da-4701-af43-122684543891.npz\")\n",
    "# for k in test_npz.keys():\n",
    "#     print(k)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 56,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-16T13:59:41.936964Z",
     "start_time": "2024-05-16T13:59:41.936957Z"
    },
    "execution": {
     "iopub.execute_input": "2025-09-19T00:59:56.808021Z",
     "iopub.status.busy": "2025-09-19T00:59:56.807870Z",
     "iopub.status.idle": "2025-09-19T02:42:36.430868Z",
     "shell.execute_reply": "2025-09-19T02:42:36.430234Z",
     "shell.execute_reply.started": "2025-09-19T00:59:56.808005Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "t_data_memmap is set to: 12000\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      " 37%|███████████████████████████████████████                                                                  | 192216/517178 [38:46<57:07, 94.81it/s]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "192196, 'playlist_arr is not a file in the archive', playlist_condition, /app2/suno/data/dpo/bluejay_t1_npz/f7939ba7-8ccb-4d79-a4c7-81bfdd9afcb2.npz.\n",
      "WTF --> 192197, skip, preference: True, 80e0d5a0-1b4b-45e4-b339-64cad1f36f5f, task: playlist_condition.\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      " 39%|█████████████████████████████████████████▏                                                               | 202676/517178 [41:11<55:19, 94.75it/s]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "202656, 'playlist_arr is not a file in the archive', playlist_condition, /app2/suno/data/dpo/bluejay_t1_npz/5a5ba9c7-4497-4464-90a3-ffe831e5ff1d.npz.\n",
      "WTF --> 202657, skip, preference: True, 8b72d2ec-498e-4d0b-b38c-3400a5ceed9e, task: playlist_condition.\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      " 93%|████████████████████████████████████████████████████████████████████████████████████████████████▎      | 483493/517178 [1:35:57<05:57, 94.11it/s]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "483478, 'playlist_arr is not a file in the archive', playlist_condition, /app2/suno/data/dpo/bluejay_t1_npz/1320d163-2827-43d7-ac09-dfd03b5c4ee7.npz.\n",
      "WTF --> 483479, skip, preference: True, 452d9e4a-c98c-4a0b-b8ce-22f2f714faf4, task: playlist_condition.\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|███████████████████████████████████████████████████████████████████████████████████████████████████████| 517178/517178 [1:42:38<00:00, 83.97it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Total 517172 clips, 86 different prompts, 3 different tags, 0 different negative tags\n",
      "19,267 hours of False\n",
      "19,176 hours of True\n",
      "gen: 18811.5 hours\n",
      "cover: 10501.8 hours\n",
      "artist_cover: 2158.3 hours\n",
      "extend: 1186.1 hours\n",
      "artist_consistency: 4038.2 hours\n",
      "overpainting: 542.8 hours\n",
      "infill: 119.8 hours\n",
      "artist_extend: 239.9 hours\n",
      "playlist_condition: 634.7 hours\n",
      "underpainting: 210.5 hours\n",
      "🚨 Error playlist_condition: 3\n",
      "\n",
      "--- Gender Distribution ---\n",
      "  female: 46,998 (9.1%)\n",
      "  male: 64,368 (12.4%)\n",
      "  unspecified: 405,809 (78.5%)\n",
      "\n",
      "--- Negative Tags Usage ---\n",
      "  has_neg_tags: 30,950 (6.0%)\n",
      "  no_neg_tags: 486,225 (94.0%)\n",
      "\n",
      "--- Control Slider Usage ---\n",
      "  has_control_slider: 172,794 (33.4% of clips)\n",
      "  no_control_slider: 344,381 (66.6% of clips)\n",
      "Done\n"
     ]
    }
   ],
   "source": [
    "make_dataset(\n",
    "    train_df, OUT_DATA_DIR, is_val=False, npz_dir=NPZ_DIR, t_data_memmap=N_TOKENS_AUDIO\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-01-29T19:46:47.549860Z",
     "start_time": "2024-01-29T19:46:47.548015Z"
    }
   },
   "source": [
    "# Validation"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-16T13:59:41.937879Z",
     "start_time": "2024-05-16T13:59:41.937870Z"
    },
    "execution": {
     "iopub.execute_input": "2025-09-19T02:42:36.431697Z",
     "iopub.status.busy": "2025-09-19T02:42:36.431526Z",
     "iopub.status.idle": "2025-09-19T02:42:37.674755Z",
     "shell.execute_reply": "2025-09-19T02:42:37.674160Z",
     "shell.execute_reply.started": "2025-09-19T02:42:36.431679Z"
    }
   },
   "outputs": [],
   "source": [
    "# verify\n",
    "mm = np.memmap(os.path.join(OUT_DATA_DIR, f\"data_val.bin\"), dtype=np.uint16, mode=\"r\")\n",
    "test_metas = read_jsonl(os.path.join(OUT_DATA_DIR, f\"meta_val.jsonl\"))\n",
    "test_info = read_json(os.path.join(OUT_DATA_DIR, f\"info_val.json\"))\n",
    "mm = mm.reshape(-1, N_TOKENS_AUDIO, 1)\n",
    "assert len(mm) == len(test_metas)\n",
    "assert mm[:100, :, 0].min() >= 0\n",
    "assert mm[:100, :, 0].max() <= 4000"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-09-19T02:42:37.675560Z",
     "iopub.status.busy": "2025-09-19T02:42:37.675398Z",
     "iopub.status.idle": "2025-09-19T02:42:37.697019Z",
     "shell.execute_reply": "2025-09-19T02:42:37.696532Z",
     "shell.execute_reply.started": "2025-09-19T02:42:37.675544Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Counter({None: 3242, 'cover': 1034, 'artist_consistency': 320, 'artist_cover': 218, 'extend': 166, 'infill': 70, 'playlist_condition': 64, 'overpainting': 58, 'underpainting': 32, 'artist_extend': 22})\n"
     ]
    }
   ],
   "source": [
    "task_counts = Counter()\n",
    "for test_meta in test_metas:\n",
    "    task_counts[test_meta.get(\"task\")] += 1\n",
    "print(task_counts)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-16T13:59:41.938629Z",
     "start_time": "2024-05-16T13:59:41.938621Z"
    },
    "execution": {
     "iopub.execute_input": "2025-09-19T02:42:37.697684Z",
     "iopub.status.busy": "2025-09-19T02:42:37.697536Z",
     "iopub.status.idle": "2025-09-19T02:42:37.713806Z",
     "shell.execute_reply": "2025-09-19T02:42:37.713381Z",
     "shell.execute_reply.started": "2025-09-19T02:42:37.697670Z"
    }
   },
   "outputs": [],
   "source": [
    "# # randomly listen to some stuff\n",
    "# from suno_utils.tasks.dac_2c_12cb import preload_models as preload_codec_models\n",
    "# from suno_utils.tasks.dac_2c_12cb import (\n",
    "#     encode as codec_encode,\n",
    "#     decode_stream_to_full_audio as codec_decode,\n",
    "#     EMBEDDING_RATE as CODEC_EMBEDDING_RATE,\n",
    "#     decode as decode\n",
    "# )\n",
    "# os.environ[\"CUDA_VISIBLE_DEVICES\"] = \"0\"\n",
    "# _ = preload_codec_models(\"/app/suno/data/dpo/models/dac_2c_25x12.pt\", device=\"cuda\")\n",
    "# assert len(test_metas) == len(mm)\n",
    "# idx_list = list(range(len(test_metas)))\n",
    "# # random.shuffle(idx_list)\n",
    "# # idx_list = [idx for idx in idx_list if \"text\" in test_metas[idx]]\n",
    "# print(len(mm))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-16T13:59:41.939205Z",
     "start_time": "2024-05-16T13:59:41.939198Z"
    },
    "execution": {
     "iopub.execute_input": "2025-09-19T02:42:37.714452Z",
     "iopub.status.busy": "2025-09-19T02:42:37.714311Z",
     "iopub.status.idle": "2025-09-19T02:42:37.729614Z",
     "shell.execute_reply": "2025-09-19T02:42:37.729179Z",
     "shell.execute_reply.started": "2025-09-19T02:42:37.714438Z"
    }
   },
   "outputs": [],
   "source": [
    "# import random\n",
    "# idx = random.choice(test_info[\"perference_0\"][\"idx_list\"])\n",
    "# assert \"original_duration_s\" in test_metas[idx]\n",
    "# # positive index should be shifted by 1\n",
    "# pos_idx = idx + 1\n",
    "# print(\n",
    "#     \"tags:\",\n",
    "#     test_metas[idx].get(\"tags\") == test_metas[pos_idx].get(\"tags\"),\n",
    "#     test_metas[idx].get(\"tags\"),\n",
    "# )\n",
    "# arr = mm[idx, 1:].copy().astype(np.int16)[:, 1:]\n",
    "# pos_arr = mm[pos_idx, 1:].copy().astype(np.int16)[:, 1:]\n",
    "# pad_idx_arr = np.where(arr == COARSE_PAD_TOKEN)[0]\n",
    "# if len(pad_idx_arr) > 0:\n",
    "#     arr = arr[: pad_idx_arr[0], :]\n",
    "# pos_pad_idx_arr = np.where(pos_arr == COARSE_PAD_TOKEN)[0]\n",
    "# if len(pos_pad_idx_arr) > 0:\n",
    "#     pos_arr = pos_arr[: pos_pad_idx_arr[0], :]\n",
    "# a = decode(arr)\n",
    "# print(\"\\n negative example \\n\", test_metas[idx])\n",
    "# a.play(compress=False)\n",
    "# pos_a = decode(pos_arr)\n",
    "# print(\"\\n positive example \\n\", test_metas[pos_idx])\n",
    "# pos_a.play(compress=False)\n",
    "# print(\n",
    "#     \"text:\",\n",
    "#     test_metas[idx].get(\"text\") == test_metas[pos_idx].get(\"text\"),\n",
    "#     test_metas[idx].get(\"text\"),\n",
    "# )"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 61,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-16T13:59:41.939977Z",
     "start_time": "2024-05-16T13:59:41.939969Z"
    },
    "execution": {
     "iopub.execute_input": "2025-09-19T02:42:37.730230Z",
     "iopub.status.busy": "2025-09-19T02:42:37.730094Z",
     "iopub.status.idle": "2025-09-19T02:42:37.744953Z",
     "shell.execute_reply": "2025-09-19T02:42:37.744523Z",
     "shell.execute_reply.started": "2025-09-19T02:42:37.730217Z"
    }
   },
   "outputs": [],
   "source": [
    "# val_df[val_df[\"tags\"] == 'a vibrant blend of experimental jazz fusion, drum-and-bass and swagger fuzzed-out guitars']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 62,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-16T13:59:41.940610Z",
     "start_time": "2024-05-16T13:59:41.940603Z"
    },
    "execution": {
     "iopub.execute_input": "2025-09-19T02:42:37.747116Z",
     "iopub.status.busy": "2025-09-19T02:42:37.746958Z",
     "iopub.status.idle": "2025-09-19T02:42:37.761886Z",
     "shell.execute_reply": "2025-09-19T02:42:37.761457Z",
     "shell.execute_reply.started": "2025-09-19T02:42:37.747101Z"
    }
   },
   "outputs": [],
   "source": [
    "# from collections import Counter\n",
    "# c = Counter()\n",
    "# for _, row in df_slice.iterrows():\n",
    "#     # print(row[\"metadata\"])\n",
    "#     for k in ast.literal_eval(row[\"metadata\"]).keys():\n",
    "#         c[k] += 1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 63,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-16T13:59:41.941167Z",
     "start_time": "2024-05-16T13:59:41.941159Z"
    },
    "execution": {
     "iopub.execute_input": "2025-09-19T02:42:37.762491Z",
     "iopub.status.busy": "2025-09-19T02:42:37.762352Z",
     "iopub.status.idle": "2025-09-19T02:42:37.777135Z",
     "shell.execute_reply": "2025-09-19T02:42:37.776710Z",
     "shell.execute_reply.started": "2025-09-19T02:42:37.762478Z"
    }
   },
   "outputs": [],
   "source": [
    "# original_npz_path = f\"/app/suno/data/dpo/7b_npz/{test_metas[idx]['id']}.npz\"\n",
    "# original_npz_path = \"/app/suno/data/dpo/7b_npz/729c3011-f672-4ccd-8d82-1cbf2b52ff69.npz\"\n",
    "# original_arr = np.load(original_npz_path)[\"v2_raw\"]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 64,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-16T13:59:41.941801Z",
     "start_time": "2024-05-16T13:59:41.941793Z"
    },
    "execution": {
     "iopub.execute_input": "2025-09-19T02:42:37.777761Z",
     "iopub.status.busy": "2025-09-19T02:42:37.777615Z",
     "iopub.status.idle": "2025-09-19T02:42:37.796942Z",
     "shell.execute_reply": "2025-09-19T02:42:37.796486Z",
     "shell.execute_reply.started": "2025-09-19T02:42:37.777747Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2613 0\n"
     ]
    }
   ],
   "source": [
    "def validation_on_metas(input_metas):\n",
    "    total_bad = 0\n",
    "    total_good = 0\n",
    "    for idx in range(len(input_metas)):\n",
    "        if idx % 2 == 0:\n",
    "            pos_idx = idx + 1\n",
    "            if input_metas[idx].get(\"tags\") != input_metas[pos_idx].get(\"tags\"):\n",
    "                print(\n",
    "                    input_metas[idx].get(\"id\"),\n",
    "                    input_metas[idx].get(\"tags\"),\n",
    "                    input_metas[pos_idx].get(\"id\"),\n",
    "                    input_metas[pos_idx].get(\"tags\"),\n",
    "                )\n",
    "                # print(test_metas[idx].get(\"text\") == test_metas[pos_idx].get(\"text\"), test_metas[idx].get(\"tags\"), test_metas[pos_idx].get(\"tags\"))\n",
    "                total_bad += 1\n",
    "            elif input_metas[idx].get(\"text\") != input_metas[pos_idx].get(\"text\"):\n",
    "                # print(test_metas[idx].get(\"text\") == test_metas[pos_idx].get(\"text\"), test_metas[idx].get(\"tags\"), test_metas[pos_idx].get(\"tags\"))\n",
    "                total_bad += 1\n",
    "            else:\n",
    "                total_good += 1\n",
    "    print(total_good, total_bad)\n",
    "    return\n",
    "\n",
    "\n",
    "validation_on_metas(test_metas)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 65,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-16T13:59:41.942520Z",
     "start_time": "2024-05-16T13:59:41.942511Z"
    },
    "execution": {
     "iopub.execute_input": "2025-09-19T02:42:37.797763Z",
     "iopub.status.busy": "2025-09-19T02:42:37.797623Z",
     "iopub.status.idle": "2025-09-19T02:42:37.856076Z",
     "shell.execute_reply": "2025-09-19T02:42:37.855625Z",
     "shell.execute_reply.started": "2025-09-19T02:42:37.797750Z"
    }
   },
   "outputs": [],
   "source": [
    "train_info = read_json(os.path.join(OUT_DATA_DIR, f\"info_tr.json\"))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 66,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-16T13:59:41.943072Z",
     "start_time": "2024-05-16T13:59:41.943065Z"
    },
    "execution": {
     "iopub.execute_input": "2025-09-19T02:42:37.856723Z",
     "iopub.status.busy": "2025-09-19T02:42:37.856582Z",
     "iopub.status.idle": "2025-09-19T02:42:37.892834Z",
     "shell.execute_reply": "2025-09-19T02:42:37.892382Z",
     "shell.execute_reply.started": "2025-09-19T02:42:37.856709Z"
    }
   },
   "outputs": [],
   "source": [
    "n_neg_tr = train_info[\"perference_0\"][\"idx_list\"]\n",
    "n_pos_tr = train_info[\"perference_1\"][\"idx_list\"]\n",
    "assert len(n_pos_tr) == len(n_neg_tr)\n",
    "# make sure they are offset by 1 and exactly 1\n",
    "for i, j in zip(n_neg_tr, n_pos_tr):\n",
    "    assert i == j - 1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 67,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-16T13:59:41.944246Z",
     "start_time": "2024-05-16T13:59:41.944237Z"
    },
    "execution": {
     "iopub.execute_input": "2025-09-19T02:42:37.893460Z",
     "iopub.status.busy": "2025-09-19T02:42:37.893320Z",
     "iopub.status.idle": "2025-09-19T02:42:37.908667Z",
     "shell.execute_reply": "2025-09-19T02:42:37.908210Z",
     "shell.execute_reply.started": "2025-09-19T02:42:37.893447Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "total samples 517172 (517178, 202)\n"
     ]
    }
   ],
   "source": [
    "total_iters = len(n_neg_tr) + len(n_pos_tr)\n",
    "print(\"total samples\", total_iters, train_df.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 68,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-09-19T02:42:37.909234Z",
     "iopub.status.busy": "2025-09-19T02:42:37.909101Z",
     "iopub.status.idle": "2025-09-19T02:42:46.237318Z",
     "shell.execute_reply": "2025-09-19T02:42:46.236695Z",
     "shell.execute_reply.started": "2025-09-19T02:42:37.909221Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "258586 0\n"
     ]
    }
   ],
   "source": [
    "metas_tr = read_jsonl(os.path.join(OUT_DATA_DIR, \"meta_tr.jsonl\"))\n",
    "validation_on_metas(metas_tr)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 69,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-09-19T02:42:46.238134Z",
     "iopub.status.busy": "2025-09-19T02:42:46.237966Z",
     "iopub.status.idle": "2025-09-19T02:42:46.259080Z",
     "shell.execute_reply": "2025-09-19T02:42:46.258601Z",
     "shell.execute_reply.started": "2025-09-19T02:42:46.238116Z"
    }
   },
   "outputs": [],
   "source": [
    "# new_metas_tr = []\n",
    "# for index, l in enumerate(metas_tr):\n",
    "#     if index % 2 == 1:\n",
    "#         last_l = new_metas_tr[-1]\n",
    "#         if l[\"tags\"] != last_l[\"tags\"]:\n",
    "#             print(l[\"tags\"], last_l[\"tags\"])\n",
    "#             l[\"tags\"] = last_l[\"tags\"]\n",
    "#     new_metas_tr.append(l)\n",
    "# validation_on_metas(new_metas_tr)\n",
    "# write_jsonl(new_metas_tr, os.path.join(OUT_DATA_DIR, \"meta_tr.jsonl\"))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 70,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-16T13:59:41.945249Z",
     "start_time": "2024-05-16T13:59:41.945241Z"
    },
    "execution": {
     "iopub.execute_input": "2025-09-19T02:42:46.259742Z",
     "iopub.status.busy": "2025-09-19T02:42:46.259589Z",
     "iopub.status.idle": "2025-09-19T02:42:46.278191Z",
     "shell.execute_reply": "2025-09-19T02:42:46.277746Z",
     "shell.execute_reply.started": "2025-09-19T02:42:46.259727Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1 epoch per batch 4, total 2020.203125\n",
      "1 epoch per batch 6, total 673.4010416666666\n",
      "1 epoch per batch 8, total 505.05078125\n"
     ]
    }
   ],
   "source": [
    "print(\"1 epoch per batch 4, total\", total_iters / 8 / 8 / 4)\n",
    "print(\"1 epoch per batch 6, total\", total_iters / 16 / 8 / 6)\n",
    "print(\"1 epoch per batch 8, total\", total_iters / 16 / 8 / 8)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 71,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-09-19T02:42:46.278813Z",
     "iopub.status.busy": "2025-09-19T02:42:46.278670Z",
     "iopub.status.idle": "2025-09-19T02:42:46.293240Z",
     "shell.execute_reply": "2025-09-19T02:42:46.292817Z",
     "shell.execute_reply.started": "2025-09-19T02:42:46.278799Z"
    }
   },
   "outputs": [],
   "source": [
    "# import time\n",
    "# time.sleep(60 * 60 * 1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 72,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-16T13:59:41.945972Z",
     "start_time": "2024-05-16T13:59:41.945964Z"
    },
    "execution": {
     "iopub.execute_input": "2025-09-19T02:42:46.294017Z",
     "iopub.status.busy": "2025-09-19T02:42:46.293880Z",
     "iopub.status.idle": "2025-09-19T02:42:46.308246Z",
     "shell.execute_reply": "2025-09-19T02:42:46.307828Z",
     "shell.execute_reply.started": "2025-09-19T02:42:46.294004Z"
    }
   },
   "outputs": [],
   "source": [
    "# !cd /home/tony/Work/tony/slurm/bluejay && sbatch sbatch_ipo_bluejay"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 73,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-09-19T02:42:46.309013Z",
     "iopub.status.busy": "2025-09-19T02:42:46.308873Z",
     "iopub.status.idle": "2025-09-19T02:42:46.335048Z",
     "shell.execute_reply": "2025-09-19T02:42:46.334593Z",
     "shell.execute_reply.started": "2025-09-19T02:42:46.308999Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Cache kept!\n"
     ]
    }
   ],
   "source": [
    "import shutil\n",
    "\n",
    "# Basic file copy\n",
    "shutil.copy(\n",
    "    \"/home/tony/Work/tony/Preference/make_dataset_bluejay_t1.ipynb\",\n",
    "    os.path.join(OUT_DATA_DIR, \"make_dataset.ipynb\"),\n",
    ")\n",
    "print(\"Cache kept!\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# some gymathtics loading prev data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 74,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-16T13:59:41.946562Z",
     "start_time": "2024-05-16T13:59:41.946555Z"
    },
    "execution": {
     "iopub.execute_input": "2025-09-19T02:42:46.335664Z",
     "iopub.status.busy": "2025-09-19T02:42:46.335527Z",
     "iopub.status.idle": "2025-09-19T02:42:46.350202Z",
     "shell.execute_reply": "2025-09-19T02:42:46.349785Z",
     "shell.execute_reply.started": "2025-09-19T02:42:46.335651Z"
    }
   },
   "outputs": [],
   "source": [
    "# prev_v3_data = \"/app/suno/data/dpo/7v_v20_full/\"\n",
    "\n",
    "# test_val_metas = read_jsonl(os.path.join(prev_v3_data, f\"meta_val.jsonl\"))\n",
    "# test_tr_metas = read_jsonl(os.path.join(prev_v3_data, f\"meta_tr.jsonl\"))\n",
    "\n",
    "# all_ids = set()\n",
    "# for meta in test_val_metas:\n",
    "#     all_ids.add(meta[\"id\"])\n",
    "# for meta in test_tr_metas:\n",
    "#     all_ids.add(meta[\"id\"])\n",
    "# print(len(all_ids), len(test_val_metas) + len(test_tr_metas))\n",
    "\n",
    "# all_ids = list(all_ids)\n",
    "# with open(\"/home/tony/Data/Preference/7b_v2/7v_v20_full_recut_id.json\", \"w\") as fp:\n",
    "#     json.dump(all_ids, fp)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 75,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-09-19T02:42:46.350815Z",
     "iopub.status.busy": "2025-09-19T02:42:46.350675Z",
     "iopub.status.idle": "2025-09-19T02:42:46.365755Z",
     "shell.execute_reply": "2025-09-19T02:42:46.365331Z",
     "shell.execute_reply.started": "2025-09-19T02:42:46.350801Z"
    }
   },
   "outputs": [],
   "source": [
    "# x_data = train_df[train_df[\"preference\"]][\"similarity\"]\n",
    "# y_data = train_df[~train_df[\"preference\"]][\"similarity\"]\n",
    "# from matplotlib.colors import LogNorm\n",
    "\n",
    "# fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(24, 10))\n",
    "\n",
    "# # 2D Histogram\n",
    "# h = ax1.hist2d(\n",
    "#     x_data,\n",
    "#     y_data,\n",
    "#     bins=(50, 50),\n",
    "#     cmap=\"coolwarm\",\n",
    "#     range=[[0, 1], [0, 1]],\n",
    "#     norm=LogNorm(),\n",
    "# )\n",
    "\n",
    "# ax1.set_xlabel(\"Semantic Distance (Preferred)\")\n",
    "# ax1.set_ylabel(\"Semantic Distance (Non-Preferred)\")\n",
    "# ax1.set_title(\n",
    "#     \"2D Histogram of Semantic Distances: Preferred vs Non-Preferred (Log Scale)\"\n",
    "# )\n",
    "\n",
    "# cbar1 = plt.colorbar(h[3], ax=ax1)\n",
    "# cbar1.set_label(\"Number of Request IDs (Log Scale)\")\n",
    "\n",
    "# # Scatter plot\n",
    "# ax2.scatter(x_data, y_data, alpha=0.1, s=1)\n",
    "# ax2.set_xlabel(\"Semantic Distance (Preferred)\")\n",
    "# ax2.set_ylabel(\"Semantic Distance (Non-Preferred)\")\n",
    "# ax2.set_title(\"Scatter Plot of Semantic Distances: Preferred vs Non-Preferred\")\n",
    "# ax2.set_xlim(0, 1)\n",
    "# ax2.set_ylim(0, 1)\n",
    "\n",
    "# plt.tight_layout()\n",
    "# plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 76,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-09-19T02:42:46.366511Z",
     "iopub.status.busy": "2025-09-19T02:42:46.366376Z",
     "iopub.status.idle": "2025-09-19T02:42:46.380850Z",
     "shell.execute_reply": "2025-09-19T02:42:46.380423Z",
     "shell.execute_reply.started": "2025-09-19T02:42:46.366498Z"
    }
   },
   "outputs": [],
   "source": [
    "# train_metas = read_jsonl(os.path.join(OUT_DATA_DIR, f\"meta_tr.jsonl\"))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 77,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-09-19T02:42:46.381454Z",
     "iopub.status.busy": "2025-09-19T02:42:46.381319Z",
     "iopub.status.idle": "2025-09-19T02:42:46.396034Z",
     "shell.execute_reply": "2025-09-19T02:42:46.395607Z",
     "shell.execute_reply.started": "2025-09-19T02:42:46.381441Z"
    }
   },
   "outputs": [],
   "source": [
    "# train_info.keys()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 78,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-09-19T02:42:46.396676Z",
     "iopub.status.busy": "2025-09-19T02:42:46.396531Z",
     "iopub.status.idle": "2025-09-19T02:42:46.411057Z",
     "shell.execute_reply": "2025-09-19T02:42:46.410636Z",
     "shell.execute_reply.started": "2025-09-19T02:42:46.396663Z"
    }
   },
   "outputs": [],
   "source": [
    "# import torch\n",
    "\n",
    "# a = torch.tensor([6.2500e-04, 3.9062e-05, 2.3462e-03])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 79,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-09-19T02:42:46.411656Z",
     "iopub.status.busy": "2025-09-19T02:42:46.411520Z",
     "iopub.status.idle": "2025-09-19T02:42:46.426105Z",
     "shell.execute_reply": "2025-09-19T02:42:46.425683Z",
     "shell.execute_reply.started": "2025-09-19T02:42:46.411643Z"
    }
   },
   "outputs": [],
   "source": [
    "# a.mean()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 80,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-09-19T02:42:46.426852Z",
     "iopub.status.busy": "2025-09-19T02:42:46.426712Z",
     "iopub.status.idle": "2025-09-19T02:42:46.441180Z",
     "shell.execute_reply": "2025-09-19T02:42:46.440761Z",
     "shell.execute_reply.started": "2025-09-19T02:42:46.426839Z"
    }
   },
   "outputs": [],
   "source": [
    "# import time\n",
    "# time.sleep(3600 * 3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 81,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-09-19T02:42:46.441965Z",
     "iopub.status.busy": "2025-09-19T02:42:46.441828Z",
     "iopub.status.idle": "2025-09-19T02:42:46.456208Z",
     "shell.execute_reply": "2025-09-19T02:42:46.455789Z",
     "shell.execute_reply.started": "2025-09-19T02:42:46.441952Z"
    }
   },
   "outputs": [],
   "source": [
    "# !cd /home/tony/Work/tony/slurm/diffusion && sbatch run_diffusion_infill.sh"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 82,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-09-19T02:42:46.456846Z",
     "iopub.status.busy": "2025-09-19T02:42:46.456702Z",
     "iopub.status.idle": "2025-09-19T02:45:00.344698Z",
     "shell.execute_reply": "2025-09-19T02:45:00.344177Z",
     "shell.execute_reply.started": "2025-09-19T02:42:46.456832Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "check subset shape (8767942, 199) (721584, 199)\n",
      "user_id\n",
      "9      1.000000\n",
      "199    1.000000\n",
      "411    1.000000\n",
      "591    0.466667\n",
      "717    0.400000\n",
      "Name: preference, dtype: float64\n"
     ]
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAk0AAAGGCAYAAABmPbWyAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8hTgPZAAAACXBIWXMAAA9hAAAPYQGoP6dpAABT6klEQVR4nO3dd1QUV/8G8AeQooINLIktUbMLsjTFGBD1FbvEisaGPYomtljRGBUbajQxCIko2DHEV4UUWzTGChI1drEAFtAEYbEhHe7vD3/M69KcRZDi8znHc+TOnTvfubvsPszMzuoIIQSIiIiIqFC6pV0AERERUXnA0EREREQkA0MTERERkQwMTUREREQyMDQRERERycDQRERERCQDQxMRERGRDAxNRERERDIwNBERERHJwNBExcLZ2RkeHh6lXUaF5+/vj44dO8LCwgK9e/cu7XLKpZCQEHTr1g2Wlpawt7cv7XJKHefjf5ydneHu7l7aZZRJw4YNw7Bhw0q7jFLH0ER57NmzB0qlEpcvX853+bBhw/Dxxx+/9naOHTuGtWvXvvY4b4uTJ0/i66+/RosWLeDl5YVp06YV2LewxygxMRFKpbLMzH14eDiUSqX0z9LSEh07dsSsWbMQExNTrNuKiorCnDlz0KhRIyxevBiLFi0q1vHLmzc9H2vXroWzs3OJbuNttm7dOhw+fPiNbCs2NhZKpRLh4eFvZHtlRaXSLoAqhgMHDkBHR0erdY4dO4bAwEBMmjSphKqqWE6fPg1dXV0sXboUBgYGpV1OsRs2bBisrKyQmZmJa9eu4aeffsKxY8fwyy+/oG7dusWyjb/++gvZ2dn48ssv0bhx42IZszzjfFQsfn5+6Nq1Kzp16lTapVRYPNJExcLAwAD6+vqlXYZWkpOTS7sErajVahgZGZXLwCRnru3t7dG7d2+4urriq6++wuzZs/H48WOEhIS81rgvU6vVAAATExOt1itMeXsevawk5iMlJaXYxqKSU56ft6WJoYmKRe5rmjIyMuDj44MuXbrAysoKrVu3xuDBg3Hq1CkAgIeHBwIDAwFA49RMjuTkZCxfvhzt27eHSqVC165dERAQACGExnZTU1OxZMkStG7dGnZ2dhg/fjzi4uLynH5au3YtlEolIiMjMX36dLRq1QpDhgwBAFy/fh0eHh7o2LEjrKys0KZNG8yZMwePHj3S2FbOGLdv38aMGTPQsmVLfPTRR1izZg2EEPjnn38wYcIEtGjRAm3atMHGjRtlzV1mZiZ8fX3RqVMnqFQqODs745tvvkF6errUR6lUYs+ePUhOTpbmas+ePbLGlyMpKQlLly6Fs7MzVCoVHBwcMGrUKFy9elWj38WLFzFmzBi0bNkSNjY2cHNzw7lz5zT6FDbX2vjoo48AvDgNIGfcn3/+Gf369YO1tTU+/PBDfPHFF/jnn3+k5c7OztJzwsHBIc9z5NixYxgyZAhsbW1hZ2eHcePG4datWxo1eXh4wM7ODvfu3cPYsWNhZ2eHGTNmAACys7OxefNmuLi4wMrKCo6Ojpg/fz6ePHmiMUbOdTNnz55F//79YWVlhY4dO+YbDp8+fYply5ZJj0u7du0wa9YsJCYmSn3S09Ph7e2Nzp07Q6VSoX379li5cqXG8yc/r5qPwMBAuLi4QKVSwcnJCZ6ennj69KnGGDmnga9cuYKhQ4fCxsYG33zzTaHbzU2pVGLRokXYv38/evToAWtrawwcOBA3btwAAAQFBaFz586wsrLCsGHDpOdDjrNnz2Ly5Mn4z3/+I+3/smXLkJqaqtEvPj4ec+bMQbt27aR9mjBhQp7xcgsODkbz5s2xYsUKrfbr4sWLGDt2LFq1agVbW1v07NkTW7Zs0egTFhYmPefs7e0xYcIEREVFafTJed7fvXsXHh4esLe3R8uWLTFnzhyNgKpUKpGcnIzg4GDpNSLnNbmw3x05rz/0Pzw9RwVKSkrSeHHOkZGR8cp1fXx84OfnhwEDBsDa2hpJSUm4cuUKrl69ijZt2mDgwIF4+PAhTp06hZUrV2qsK4TAhAkTEB4ejv79+8PCwgInTpzAypUrERcXh7lz50p9PTw8sH//fvTu3Rs2NjY4c+YMxo0bV2BdU6ZMQePGjfHFF19IASw0NBQxMTHo168fateujVu3bmHnzp2IjIzEzp0785x2/OKLL9C0aVNMnz4dx44dww8//IAaNWogKCgIH330EWbMmIFff/0VK1asgJWVFVq1alXoXM2bNw/BwcHo2rUrRo0ahUuXLsHPzw9RUVHw9fUFAKxcuRI7d+7EpUuXsGTJEgBAixYtXvk4yLVgwQIcPHgQbm5uaNq0KR4/foxz584hKioKlpaWAF68wI8dOxYqlQoTJ06Ejo4O9uzZgxEjRmDHjh2wtrbWGDO/udbGvXv3AAA1atR45bg//PADvvvuO3Tv3h39+/dHYmIitm/fjqFDhyIkJATVqlXD3LlzERISgkOHDmHhwoWoUqWKFNRDQkLg4eEBJycnzJgxAykpKfjxxx8xZMgQBAcHo0GDBtL2MzMzpeA4e/ZsGBkZAQDmz5+P4OBg9OvXT3pzDwwMxLVr1/Djjz9qHIm9e/cupkyZgv79+6Nv377YvXs3PDw8YGlpiQ8++AAA8Pz5cwwdOhRRUVFwdXVF8+bN8ejRIxw5cgRxcXGoVasWsrOzMWHCBJw7dw6ffPIJmjZtips3b2LLli24c+cOvv/++wLnt7D5WLt2LXx8fODo6IjBgwfj9u3b+PHHH3H58uU8+/L48WOMHTsWLi4u6NWrF0xNTbV+rM+ePYsjR45Ib+Tr16/H+PHj8emnn2LHjh0YMmQInjx5An9/f8ydOxdbt26V1j1w4ABSU1MxePBg1KhRA5cuXcL27dvx77//wtvbW+o3adIkREZGws3NDfXr10diYiJOnTqFf/75R+PxfdlPP/2EBQsWwN3dHV988YXs/Tl16hTc3d1Rp04dDB8+HGZmZoiKisLRo0cxYsQIAC9ed8aOHYsGDRpg4sSJSE1Nxfbt2zF48GDs2bMnT01Tp05FgwYNMG3aNFy7dg3//e9/UatWLcycORPAi9eIefPmwdraGp988gkAoFGjRhpj5Pe7I+f1h14iiHLZvXu3UCgUhf5zcXHRWKdDhw5i9uzZ0s+9evUS48aNK3Q7np6eQqFQ5Gk/dOiQUCgU4vvvv9donzRpklAqleLu3btCCCGuXLkiFAqFWLp0qUY/Dw8PoVAohLe3t9Tm7e0tFAqFmDZtWp7tpaSk5Gn77bffhEKhEGfOnMkzxldffSW1ZWZminbt2gmlUin8/Pyk9idPnghra2uNOclPRESEUCgU4ssvv9RoX758uVAoFCIsLExqmz17trC1tS10vBxubm55HqMcarU6z/y0bNlSeHp6Fjhedna26NKlixg9erTIzs6W2lNSUoSzs7MYNWqU1FbYXOfn9OnTQqFQiF27dgm1Wi3i4uLE0aNHRYcOHYRSqRSXLl0qdNzY2FhhYWEhfvjhB432GzduiObNm2u054yhVqultqSkJGFvby/mzZunsX58fLxo2bKlRvvs2bOFQqEQq1at0uh75swZoVAoxC+//KLRfvz48TztHTp0yPPcUqvVQqVSieXLl0tt3333nVAoFOL333/PM2c5j0FISIgwNzfXGEsIIX788UehUCjEuXPn8qz7svzmQ61WC0tLSzF69GiRlZUltW/fvl16nHK4ubkJhUIhfvzxx0K3UxiFQiFUKpWIiYmR2oKCgoRCoRBt2rQRz549k9pXr14tFAqFRt/8fn/9/PyEUqkU9+/fF0K8+H1UKBTC39+/0Fo6dOggvW5t2bJFKJVK4evrq9X+ZGZmCmdnZ9GhQwfx5MkTjWUv/+707t1bODg4iEePHkltERERwtzcXMyaNUtqy3mM5syZozHW559/Lj788EONNltb23xfcwr63dHm9cfNzU24ubm9Yu8rPp6eowLNnz8fmzZtyvPv5dNoBalWrRpu3bqFO3fuaL3d48ePQ09PL8/HW0ePHg0hBI4fPw4AOHHiBADkOfXj5uZW4NiDBg3K05ZzpAAA0tLSkJiYCBsbGwDIc3oKAPr37y/9X09PDyqVCkIIjfZq1arh/ffff+Wnv44dOwYAGDVqlEb76NGjNZaXtGrVquHixYuIi4vLd3lERATu3LmDnj174tGjR0hMTERiYiKSk5Ph4OCAM2fOIDs7W2Od/Oa6MHPnzoWDgwPatm2LcePGISUlBcuXL4eVlVWh4x46dAjZ2dno3r27VFdiYiLMzMzQuHHjV366JzQ0FE+fPoWLi4vG+rq6urCxscl3/cGDB2v8fODAAZiYmKBNmzYaY1haWqJKlSp5xmjWrJnGx/tr1aqV5/ny+++/w9zcHJ07d86z/ZyjnwcOHEDTpk3RpEkTje3mnNosyiebQkNDkZGRgeHDh0NX939vEQMGDICxsXGe56SBgQH69eun9XZe5uDgoHFkJef3r0uXLjA2Npbac45mvjxPL//+JicnIzExEXZ2dhBC4Nq1a1IffX19/PXXX3lOl+Znw4YNWLp0KWbMmIHPPvtMq325du0aYmNjMXz4cFSrVk1jWc7j9vDhQ0RERKBv374aR1LNzc3h6OiY7+997ue9vb09Hj9+jKSkJNm15R6jrLz+lCc8PUcFsra2zvOGBQDVq1fPc71PbpMnT8Znn32Grl27QqFQwMnJCb1794a5ufkrt3v//n3UqVNH48USAJo2bSotB4AHDx5AV1c3z2Hswj4FlN9h+MePH8PHxwf79u2TLozN8ezZszz93333XY2fTUxMYGhoiFq1auVpf/z4cYG15OyLrq5unsPotWvXRrVq1aR9LQkvn3acMWMGPDw88J///AeWlpZo3749+vTpg4YNGwKAFH5nz55d4HjPnj1D9erVpZ8LOuVRkM8//xz29vbQ1dVFzZo10bRpU1SqlPclKve4d+7cgRACXbp0yXfc/MbIvT4A6bRJbrmfh5UqVUK9evU02u7evYtnz57BwcEh3zFyP6/eeeedPH2qV6+u8YZ+7969Avfp5e1GRUXJ3q4cDx48AAA0adJEo93AwAANGzbM85ysW7fua384Ifd85Mx57nnOuWD95WurHjx4AG9vbxw5ciRPIMoJFAYGBpgxYwZWrFiBNm3awMbGBv/5z3/Qp08f1K5dW2Odv/76C0ePHsXYsWPx6aefar0vOYFOoVAU2Cdnjt9///08y5o2bYqTJ08iOTkZVapUkdpzv+7kBLInT57keY4WJPfvTmm+/pRXDE1UIlq1aoVDhw7hjz/+wKlTp7Br1y5s2bIFnp6eGDBgQKnVZWhomKdt6tSpOH/+PMaMGQMLCwtUqVIF2dnZ+PTTT/O9Fuflv75z6Onp5bu9/NbPj7a3a3gVAwODPBfC5shpf/mNrkePHrC3t8ehQ4dw6tQpBAQEYMOGDVi7di3at28v7cesWbNgYWGR77gvv8AD+c91YRQKBRwdHV/ZL/e42dnZ0NHRwYYNG/J9HHLXlVvOvq1cuTLPGyiQ97E1MDDI8xzIzs6GqakpVq1ale82cgfqgp4v2srOzoZCocCcOXPyXZ47dJSEl4/0FFVB8/Gq36usrCyMGjUKT548waeffoomTZqgSpUqiIuLg4eHh8bRz5EjR8LZ2RmHDx/GyZMn8d1332H9+vXYsmULmjdvLvX74IMP8PTpU/z8888YOHCg9IdDacvvdQeQ/xoDFPw7WdyvPxUZQxOVmBo1asDV1RWurq54/vw53NzcsHbtWik0FfSLWr9+fYSFhSEpKUnjL6jo6GhpOfDiL6/s7GzExsbivffek/rdvXtXdo1PnjxBWFgYJk2ahIkTJ0rtRTmtWBT169dHdnY27t69Kx1JA4CEhAQ8ffpU2teijBseHo7U1NQ8b2q3b9+W+rysTp06GDp0KIYOHQq1Wo2+ffti3bp1aN++vfTGYWxsLCvYvEmNGjWCEAINGjTI9y/3V8nZN1NT0yLvW6NGjRAWFoYWLVoUS4jIGTP3p/fy63P9+nU4ODgU2xtfzhGN6OhojcCQnp6O2NjYMvX437x5E3fu3MGKFSvQp08fqT3nU7q5NWrUCKNHj8bo0aNx584d9OnTBxs3btQIuzVr1oS3tzeGDBmCkSNHYseOHVrdJyxnzm7evFngXOXMcc7v4suio6NRs2bNV4b94lBSrz8VGa9pohKR+/Rd1apV0ahRI42PsVauXBkA8nyMuV27dsjKypJuSZBj8+bN0NHRQbt27QAATk5OAIAdO3Zo9Nu+fbvsOgv6Szb3R4NLSvv27fPd3qZNmzSWa6tdu3bIyMhAUFCQRnt2drb06aecUzpZWVl5TkOampqiTp060uOlUqnQqFEjbNy4Ec+fP8+zvfw+ZfmmdOnSBXp6evDx8cnzV7cQ4pWnktu2bQtjY2P4+fnl+8lQOfvWvXt3ZGVl5ftptczMzDzPcTm6dOmC69ev49ChQ3mW5exn9+7dERcXh507d+bpk5qaWqR78Tg6OkJfXx/btm3TmM9du3bh2bNnRX5OloScoy8v1ymE0Ph0HfDi3lFpaWkabY0aNULVqlXz/Wh9vXr1sGnTJqSlpWH06NGvfA69zNLSEg0aNMDWrVvzPO45ddapUwcWFhYICQnR6HPz5k2cOnWqyHNcpUoVrZ5rJfX6U5HxSBOVCBcXF3z44YewtLREjRo1cPnyZekj7TlyPsq+ZMkSODk5QU9PDy4uLnB2dkbr1q3x7bff4v79+1AqlTh16hT++OMPjBgxQjr/nnP/pi1btuDx48fSLQdyjhLJ+cvb2NgYrVq1gr+/PzIyMlC3bl2cOnXqlfduKS7m5ubo27cvfvrpJzx9+hStWrXC5cuXERwcjE6dOkkX9GrL2dkZTk5O8PLywuXLl2FnZ4eUlBQcOXIEf//9N6ZOnSqdMnr+/Dnat2+Prl27wtzcHFWqVEFoaCguX74s3edFV1cXS5YswdixY/Hxxx+jX79+qFu3LuLi4hAeHg5jY2OsW7eu2OZFG40aNcLUqVOxevVq3L9/H506dULVqlURGxuLw4cP45NPPsGYMWMKXN/Y2BgLFy7ErFmz0K9fP/To0QO1atXCgwcPcOzYMbRo0QLz588vtIYPP/wQAwcOhJ+fHyIiItCmTRvo6+vjzp07OHDgAL788kt069ZNq/0aM2YMDh48iClTpsDV1RWWlpZ48uQJjhw5Ak9PT5ibm6N3797Yv38/FixYgPDwcLRo0QJZWVmIjo7GgQMH4O/vn+91iYWpVasW3N3d4ePjg08//RTOzs64ffs2duzYASsrK/Tq1Uur8UpSkyZN0KhRI6xYsQJxcXEwNjbGwYMH8wSHO3fuYOTIkejWrRuaNWsGPT09HD58GAkJCXBxccl37MaNGyMgIADDhw/HmDFjsHXrVlnXDunq6mLhwoWYMGEC+vTpI93KJDo6GpGRkQgICADw4lT32LFjMXDgQPTv31+65YCJiYnGUW9tWFpaIiwsDJs2bUKdOnXQoEED6aL6/JTU609FxtBEJWLYsGE4cuQITp06hfT0dLz77ruYOnWqxptXly5dMGzYMOzduxe//PILhBBwcXGBrq4ufvjhB3h7e2Pfvn3Ys2cP6tevj1mzZkmf6sixYsUKmJmZYe/evTh06BAcHR3x7bffolu3brIvTl29ejUWL16MHTt2QAiBNm3aYMOGDWjbtm2xzklBlixZggYNGiA4OBiHDx+GmZkZ3N3di/zCCUCaw/Xr12Pv3r34/fffUalSJSgUCnz99dcab3xGRkbSjUd///13CCHQqFEjLFiwQOOTia1bt8ZPP/2E77//Htu3b0dycjJq164t3YywNI0bNw7vvfceNm/eLN1bpl69emjTpo2s7zrr2bMn6tSpg/Xr1yMgIADp6emoW7cu7O3tZX8ybNGiRVCpVAgKCsK3334LPT091K9fH7169SrSPbWqVq2KwMBArF27FocOHUJwcDBMTU3h4OAgnS7S1dWFr68vNm/ejJ9//hmHDh1C5cqV0aBBAwwbNqxIpyuBF/c0qlWrFrZv3w4vLy9Ur14dn3zyCaZNm1am7vyvr6+PdevWYcmSJfDz84OhoSE6d+6MoUOHanyhdb169eDi4oKwsDD88ssv0NPTQ5MmTbBmzRp07dq1wPGVSiU2bNiAkSNHYvz48fD395d1+rVt27bYsmULfH19sXHjRggh0LBhQ+n+ScCLI3r+/v7w9vaGt7c3KlWqhFatWmHmzJlFvo7Kw8MD8+fPx5o1a5Camoq+ffsWGpqAknn9qch0hDZXkRGVAxEREejTp0+ecEBERPQ6eE0TlWv5fUJsy5Yt0NXVfeWduImIiLTB03NUrvn7++PKlSv46KOPoKenh+PHj+P48eMYOHBgvvfCISIqqsePHxf6NVJ6enp5bi9BFQtPz1G5durUKfj4+CAqKgrJycl455130Lt3b4wfP/6VNzUkItLGsGHD8NdffxW4vH79+jhy5MgbrIjeNIYmIiIiGa5cuVLoR/oNDQ3RsmXLN1gRvWkMTUREREQy8EJwIiIiIhkYmoiIiIhkYGgiIiIikoEfLypmavUz8CoxIiKi8kNHBzA1NXllP4amYiYEGJqIiIgqIJ6eIyIiIpKBoYmIiIhIBoYmIiIiIhkYmoiIiIhkYGgiIiIikoGhiYiIiEgGhiYiIiIiGRiaiIiIiGRgaCIiIiKSgaGJiIiISAaGJiIiIiIZ+N1zREREVCbFxsYgMVEt/VyrlikaNGhYavUwNBEREVGZExsbAwdHe6SlpkhthkaVERZ6ttSCE0MTERERlTmJiWqkpabA9OPp0DdtiAx1DNS/rUZiopqhiYiIiCg3fdOGMKzXrLTLAMALwYmIiIhkYWgiIiIikoGhiYiIiEgGhiYiIiIiGRiaiIiIiGRgaCIiIiKSgaGJiIiISAaGJiIiIiIZGJqIiIiIZGBoIiIiIpKBoYmIiIhIBoYmIiIiIhkYmoiIiIhkYGgiIiIikoGhiYiIiEgGhiYiIiIiGRiaiIiIiGRgaCIiIiKSgaGJiIiISAaGJiIiIiIZGJqIiIiIZGBoIiIiIpKBoYmIiIhIhjITmtavXw+lUomlS5dKbWlpafD09ETr1q1hZ2eHSZMmISEhQWO9Bw8eYNy4cbCxsYGDgwNWrFiBzMxMjT7h4eHo27cvVCoVOnfujD179uTZfmBgIJydnWFlZYUBAwbg0qVLJbOjREREVC6VidB06dIlBAUFQalUarQvW7YMf/75J9asWYNt27bh4cOHmDhxorQ8KysL7u7uyMjIQFBQEJYvX47g4GB4e3tLfWJiYuDu7o7WrVvj559/xogRIzBv3jycOHFC6rNv3z54eXnh888/R3BwMMzNzTFmzBio1eqS33kiIiIqF0o9ND1//hwzZ87EkiVLUL16dan92bNn2L17Nzw8PODg4ACVSoVly5bh/PnzuHDhAgDg5MmTiIyMxNdffw0LCwu0b98eU6ZMQWBgINLT0wEAQUFBaNCgATw8PNC0aVO4ubmha9eu2Lx5s7StTZs24ZNPPoGrqyuaNWsGT09PGBkZYffu3W9yKoiIiKgMK/XQtGjRIrRv3x6Ojo4a7VeuXEFGRoZGe9OmTfHuu+9KoenChQtQKBQwMzOT+jg5OSEpKQmRkZFSHwcHB42xnZycpDHS09Nx9epVje3o6urC0dER58+fL85dJSIionKsUmlufO/evbh27Rp27dqVZ1lCQgL09fVRrVo1jXZTU1PEx8dLfV4OTACkn1/VJykpCampqXjy5AmysrJgamqaZzvR0dGvt4NERERUYZRaaPrnn3+wdOlSbNy4EYaGhqVVBhEREZEspRaarl69CrVajX79+kltWVlZOHPmDAIDAxEQEICMjAw8ffpU42iTWq1G7dq1Abw4YpT7U245n657uU/uT9wlJCTA2NgYRkZG0NXVhZ6eXp6LvtVqdZ4jVERERPT2KrVrmj766CP8+uuvCAkJkf6pVCr07NlT+r++vj7CwsKkdaKjo/HgwQPY2toCAGxtbXHz5k2NwBMaGgpjY2M0a9ZM6nP69GmNbYeGhkpjGBgYwNLSUmM72dnZCAsLg52dXQntPREREZU3pXakydjYGAqFQqOtSpUqqFGjhtTu6uqK5cuXo3r16jA2NsaSJUtgZ2cnBR4nJyc0a9YMs2bNwsyZMxEfH481a9Zg6NChMDAwAAAMGjQIgYGBWLlyJVxdXXH69Gns378ffn5+0nZHjRqF2bNnQ6VSwdraGlu2bEFKSorGUTAiIiJ6u5XqheCvMnfuXOjq6mLy5MlIT0+Hk5MTFixYIC3X09PDunXrsHDhQgwcOBCVK1dG3759MXnyZKlPw4YN4efnBy8vL2zduhX16tXDkiVL0LZtW6lPjx49kJiYCG9vb8THx8PCwgL+/v48PUdEREQSHSGEKO0iKpKEhGfgjBIREb2eS5cuoFOndqg3Yg0M6zVD2r+R+HfLVBw+fBzW1rbFui0dHcDMzOSV/Ur9Pk1ERERE5QFDExEREZEMDE1EREREMjA0EREREcnA0EREREQkA0MTERERkQwMTUREREQyMDQRERERycDQRERERCQDQxMRERGRDAxNRERERDIwNBERERHJwNBEREREJANDExEREZEMDE1EREREMjA0EREREcnA0EREREQkA0MTERERkQwMTUREREQyMDQRERERycDQRERERCQDQxMRERGRDAxNRERERDIwNBERERHJwNBEREREJANDExEREZEMDE1EREREMjA0EREREcnA0EREREQkA0MTERERkQwMTUREREQyMDQRERERycDQRERERCQDQxMRERGRDAxNRERERDIwNBERERHJwNBEREREJANDExEREZEMDE1EREREMjA0EREREcnA0EREREQkA0MTERERkQwMTUREREQyMDQRERERyaB1aAoODsbRo0eln1euXAl7e3sMGjQI9+/fL87aiIiIiMoMrUPTunXrYGhoCAA4f/48duzYgZkzZ6JGjRrw8vIq9gKJiIiIyoJK2q7w77//onHjxgCAw4cPo0uXLhg4cCBatGiBYcOGFXuBRERERGWB1keaqlSpgsePHwMATp06BUdHRwCAoaEh0tLSirU4IiIiorJC6yNNjo6OmDdvHiwsLHDnzh20b98eAHDr1i3Ur1+/2AskIiIiKgu0PtK0YMEC2NnZITExEd7e3qhZsyYA4OrVq3BxcSn2AomIiIjKAq2ONGVmZmLr1q0YO3Ys6tWrp7Fs8uTJxVoYERERUVmi1ZGmSpUqISAgAJmZmSVVDxEREVGZpPU1TR999BHOnDmDBg0alEQ9VIDY2BgkJqqln2vVMkWDBg1LsSIiIqK3i9ahqV27dli9ejVu3rwJS0tLVK5cWWN5x44di604eiE2NgYOjvZIS02R2gyNKiMs9CyDExER0RuidWjy9PQEAGzatCnPMh0dHURERMgea8eOHfjxxx+lO4l/8MEH+Oyzz6RP5KWlpWH58uXYt28f0tPT4eTkhAULFsDMzEwa48GDB1i4cCHCw8NRpUoV9OnTB9OnT0elSv/btfDwcCxfvhy3bt3CO++8gwkTJqBfv34atQQGBiIgIADx8fEwNzfHV199BWtra/kTU4ISE9VIS02B6cfToW/aEBnqGKh/W43ERDVDExER0RuidWi6fv16sW28Xr16mDFjBho3bgwhBEJCQvD5558jODgYH3zwAZYtW4Zjx45hzZo1MDExweLFizFx4kQEBQUBALKysuDu7g4zMzMEBQXh4cOHmD17NvT19TFt2jQAQExMDNzd3TFo0CCsWrUKYWFhmDdvHmrXro22bdsCAPbt2wcvLy94enrCxsYGW7ZswZgxY3DgwAGYmpoW2/6+Ln3ThjCs16y0yyAiInorvdYX9r7uzSydnZ3Rvn17vPfee3j//ffxxRdfoEqVKrhw4QKePXuG3bt3w8PDAw4ODlCpVFi2bBnOnz+PCxcuAABOnjyJ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",
      "text/plain": [
       "<Figure size 600x400 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "def get_control_slider(metadata):\n",
    "    if \"param_experiment\" in metadata:\n",
    "        exp = metadata.get(\"param_experiment\", \"\")\n",
    "        if exp:\n",
    "            if exp == \"mask_control_slider\":\n",
    "                if not metadata.get(\"control_sliders\", None):\n",
    "                    return False\n",
    "                else:\n",
    "                    return True\n",
    "            return None\n",
    "\n",
    "df[\"mask_control\"] = df.apply(\n",
    "    lambda row: get_control_slider(row[\"metadata\"]), axis=1\n",
    ")\n",
    "masked_request_id = df[~df[\"mask_control\"].isna()][\"request_id\"].unique()\n",
    "subset_df = df[df[\"request_id\"].isin(masked_request_id)].copy()\n",
    "print(\"check subset shape\", df.shape, subset_df.shape)\n",
    "# control masked\n",
    "user_pref_pct = (\n",
    "    subset_df[subset_df[\"mask_control\"] == True].groupby(\"user_id\")[\"preference\"]\n",
    "    .apply(lambda x: x.mean())\n",
    ")\n",
    "print(user_pref_pct.head())\n",
    "# Plot a histogram of the user preference percentages\n",
    "plt.figure(figsize=(6, 4))\n",
    "plt.hist(user_pref_pct, bins=np.linspace(0, 1, 100), edgecolor=\"black\")\n",
    "plt.xlabel(\"Preference % for mask_control\")\n",
    "plt.ylabel(\"Number of Users\")\n",
    "plt.title(\"Histogram of User Preference for 'mask_control'\")\n",
    "plt.tight_layout()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 83,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-09-19T02:45:00.345457Z",
     "iopub.status.busy": "2025-09-19T02:45:00.345301Z",
     "iopub.status.idle": "2025-09-19T02:45:01.534554Z",
     "shell.execute_reply": "2025-09-19T02:45:01.534084Z",
     "shell.execute_reply.started": "2025-09-19T02:45:00.345441Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "67583"
      ]
     },
     "execution_count": 83,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "user_counts = subset_df.groupby(\"user_id\")[\"preference\"].count()\n",
    "eligible_users = user_counts[user_counts >= 4].index\n",
    "len(eligible_users)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 84,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-09-19T02:45:01.535188Z",
     "iopub.status.busy": "2025-09-19T02:45:01.535044Z",
     "iopub.status.idle": "2025-09-19T02:45:03.688721Z",
     "shell.execute_reply": "2025-09-19T02:45:03.688030Z",
     "shell.execute_reply.started": "2025-09-19T02:45:01.535174Z"
    }
   },
   "outputs": [],
   "source": [
    "# control masked\n",
    "eligible_user_pref_pct = (\n",
    "    subset_df[subset_df[\"user_id\"].isin(eligible_users) & (subset_df[\"mask_control\"] == True)].groupby(\"user_id\")[\"preference\"]\n",
    "    .apply(lambda x: x.mean())\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 85,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-09-19T02:45:03.689551Z",
     "iopub.status.busy": "2025-09-19T02:45:03.689389Z",
     "iopub.status.idle": "2025-09-19T02:45:03.869212Z",
     "shell.execute_reply": "2025-09-19T02:45:03.868740Z",
     "shell.execute_reply.started": "2025-09-19T02:45:03.689534Z"
    }
   },
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 600x400 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Plot a histogram of the user preference percentages\n",
    "plt.figure(figsize=(6, 4))\n",
    "plt.hist(eligible_user_pref_pct, bins=np.linspace(0, 1, 20), edgecolor=\"black\")\n",
    "plt.xlabel(\"Preference % for mask_control\")\n",
    "plt.ylabel(\"Number of Users\")\n",
    "plt.title(\"Histogram of User Preference for 'mask_control'\")\n",
    "plt.tight_layout()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 86,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-09-19T02:45:03.869907Z",
     "iopub.status.busy": "2025-09-19T02:45:03.869754Z",
     "iopub.status.idle": "2025-09-19T02:45:03.890756Z",
     "shell.execute_reply": "2025-09-19T02:45:03.890338Z",
     "shell.execute_reply.started": "2025-09-19T02:45:03.869891Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.3333333333333333"
      ]
     },
     "execution_count": 86,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "eligible_user_pref_pct[172918] # kakermix"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## sliders"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 87,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-09-19T02:45:03.891357Z",
     "iopub.status.busy": "2025-09-19T02:45:03.891221Z",
     "iopub.status.idle": "2025-09-19T02:45:03.909175Z",
     "shell.execute_reply": "2025-09-19T02:45:03.908734Z",
     "shell.execute_reply.started": "2025-09-19T02:45:03.891344Z"
    }
   },
   "outputs": [],
   "source": [
    "from typing import Any\n",
    "import pandas as pd\n",
    "\n",
    "def map_control_sliders_to_df(df: pd.DataFrame) -> pd.DataFrame:\n",
    "    \"\"\"Extracts 'style_weight' and 'weirdness_constraint' from the 'control_sliders' dict in the 'metadata' column\n",
    "    and adds them as new columns to the DataFrame.\n",
    "\n",
    "    Args:\n",
    "        df (pd.DataFrame): DataFrame with a 'metadata' column containing a 'control_sliders' dict.\n",
    "\n",
    "    Returns:\n",
    "        pd.DataFrame: DataFrame with added 'style_weight' and 'weirdness_constraint' columns.\n",
    "\n",
    "    Raises:\n",
    "        KeyError: If 'control_sliders', 'style_weight', or 'weirdness_constraint' are missing in any row.\n",
    "        TypeError: If the extracted values are not floats.\n",
    "\n",
    "    Example:\n",
    "        >>> import pandas as pd\n",
    "        >>> data = [{'metadata': {'control_sliders': {'style_weight': 0.89, 'weirdness_constraint': 0.8}}}]\n",
    "        >>> df = pd.DataFrame(data)\n",
    "        >>> df = map_control_sliders_to_df(df)\n",
    "        >>> df[['style_weight', 'weirdness_constraint']].iloc[0].tolist()\n",
    "        [0.89, 0.8]\n",
    "    \"\"\"\n",
    "    # Vectorized extraction for performance\n",
    "    sliders = df[\"metadata\"].map(lambda m: m.get(\"control_sliders\", {}))\n",
    "    style_weight = sliders.map(lambda s: s.get(\"style_weight\", None))\n",
    "    weirdness_constraint = sliders.map(lambda s: s.get(\"weirdness_constraint\", None))\n",
    "    audio_weight = sliders.map(lambda s: s.get(\"audio_weight\", None))\n",
    "\n",
    "    df[\"style_weight\"] = style_weight\n",
    "    df[\"weirdness_constraint\"] = weirdness_constraint\n",
    "    df[\"audio_weight\"] = audio_weight\n",
    "    return df\n",
    "\n",
    "def print_percentiles(\n",
    "    data: np.ndarray,\n",
    "    percentiles: list[float] = [5, 10, 20, 25, 50, 75, 80, 90, 95]\n",
    ") -> None:\n",
    "    \"\"\"Prints specified percentiles of the data.\n",
    "\n",
    "    Args:\n",
    "        data (np.ndarray): Array of values to compute percentiles for.\n",
    "        percentiles (list[float], optional): List of percentiles to print. Defaults to [5, 10, 20, 25, 50, 75, 80, 90, 95].\n",
    "\n",
    "    Example:\n",
    "        >>> print_percentiles(np.array([1, 2, 3, 4, 5]))\n",
    "    \"\"\"\n",
    "    data = data[~data.isna()]\n",
    "    results = np.percentile(data, percentiles)\n",
    "    print(\"Percentiles:\")\n",
    "    for p, v in zip(percentiles, results):\n",
    "        print(f\"  {p:>3}%: {v:.4f}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 88,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-09-19T02:45:03.909914Z",
     "iopub.status.busy": "2025-09-19T02:45:03.909773Z",
     "iopub.status.idle": "2025-09-19T02:45:07.648517Z",
     "shell.execute_reply": "2025-09-19T02:45:07.647886Z",
     "shell.execute_reply.started": "2025-09-19T02:45:03.909900Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>style_weight</th>\n",
       "      <th>weirdness_constraint</th>\n",
       "      <th>audio_weight</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>count</th>\n",
       "      <td>672508.000000</td>\n",
       "      <td>638844.000000</td>\n",
       "      <td>428082.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>mean</th>\n",
       "      <td>0.751829</td>\n",
       "      <td>0.405064</td>\n",
       "      <td>0.662971</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>std</th>\n",
       "      <td>0.229870</td>\n",
       "      <td>0.278658</td>\n",
       "      <td>0.295393</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>min</th>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>25%</th>\n",
       "      <td>0.640000</td>\n",
       "      <td>0.150000</td>\n",
       "      <td>0.470000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>50%</th>\n",
       "      <td>0.800000</td>\n",
       "      <td>0.400000</td>\n",
       "      <td>0.740000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>75%</th>\n",
       "      <td>0.950000</td>\n",
       "      <td>0.660000</td>\n",
       "      <td>0.950000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>max</th>\n",
       "      <td>1.000000</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>1.000000</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "        style_weight  weirdness_constraint   audio_weight\n",
       "count  672508.000000         638844.000000  428082.000000\n",
       "mean        0.751829              0.405064       0.662971\n",
       "std         0.229870              0.278658       0.295393\n",
       "min         0.000000              0.000000       0.000000\n",
       "25%         0.640000              0.150000       0.470000\n",
       "50%         0.800000              0.400000       0.740000\n",
       "75%         0.950000              0.660000       0.950000\n",
       "max         1.000000              1.000000       1.000000"
      ]
     },
     "execution_count": 88,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df_total = map_control_sliders_to_df(df_total)\n",
    "df_total[[\"style_weight\",\"weirdness_constraint\",\"audio_weight\"]].describe()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 89,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-09-19T02:45:07.651906Z",
     "iopub.status.busy": "2025-09-19T02:45:07.651410Z",
     "iopub.status.idle": "2025-09-19T02:45:07.973351Z",
     "shell.execute_reply": "2025-09-19T02:45:07.972733Z",
     "shell.execute_reply.started": "2025-09-19T02:45:07.651886Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Percentiles:\n",
      "    5%: 0.2800\n",
      "   10%: 0.4500\n",
      "   20%: 0.6000\n",
      "   25%: 0.6400\n",
      "   50%: 0.8000\n",
      "   75%: 0.9500\n",
      "   80%: 1.0000\n",
      "   90%: 1.0000\n",
      "   95%: 1.0000\n"
     ]
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAxYAAAHqCAYAAACZcdjsAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8hTgPZAAAACXBIWXMAAA9hAAAPYQGoP6dpAABuLklEQVR4nO3deXQUZfo24Lu7k85OBrKAJAwyAQJINgwyiYEMi8CPiMiOLBFEkUURBwYREGSRICKyDiCbhmFEVECQ4IzoiFHCnsCECYssSmAGsiixk07v3x98KdJkIUl3uiv93tc5nEOqqquet+9A+klVvaWwWCwWEBERERER2UDp7AKIiIiIiKjhY2NBREREREQ2Y2NBREREREQ2Y2NBREREREQ2Y2NBREREREQ2Y2NBREREREQ2Y2NBREREREQ2Y2NBREREREQ2Y2NBREREREQ2Y2NBRFRHa9asQXh4uEOONWbMGIwZM0b6+tixYwgPD8eXX37pkOPPmjULPXr0cMix6qq4uBhz5szB448/jvDwcLz11lvOLgkAEB4ejjVr1ji7jFrJzc1FeHg4du/eXefXbtmypR4qIyI5Y2NBRARg9+7dCA8Pl/5EREQgISEB48ePR2pqKjQajV2Oc+vWLaxZswY5OTl22Z89ybm2mti4cSP27NmDZ555BsuWLcOAAQOq3Fav1+PDDz/E008/jU6dOiE2NhZJSUl44403cPnyZWm706dPY82aNSgqKnLEEB6oX79+eOqppyos/+qrrxAeHo7Ro0dXWPfpp58iPDwc33//vSNKrJXDhw83uKaLiKrm5uwCiIjkZOrUqQgNDYXRaER+fj6OHz+OJUuW4IMPPsBf//pXtGvXTtp20qRJmDBhQq32f/v2baxduxYhISFo3759jV/niN/+VlfbokWLYLFY6r0GWxw9ehRRUVF46aWXHrjt1KlT8d133yEpKQlDhw6F0WjElStX8O233yImJgZhYWEAgMzMTKxduxYDBw5Eo0aN6nsID/Too4/i008/xW+//QY/Pz9p+enTp+Hm5oZ///vfMBgMcHd3t1qnUqkQHR1d4+OEhITg7NmzcHOr348Jhw8fxo4dO/Dyyy/X63GIyDHYWBARldOtWzdERERIX7/44ovIyMjAxIkTMXnyZKSlpcHT0xMA4ObmVu8fvLRaLby8vKBWq+v1OA9S/oOqXBUUFKB169YP3O7s2bP417/+hVdffRUTJ060WmcymWRzdqIyjz76KHbt2oXTp08jMTFRWn769Gn07dsXX3zxBc6dO2fVRJw6dQrh4eHw9fWt8XEUCgU8PDzsWToRCYCXQhERPUBcXBwmT56MGzduYN++fdLyyu6x+OGHH/DMM88gNjYWMTEx6NOnD1asWAHg7n0RQ4YMAQC8/vrr0mVXZdexjxkzBk8++SSys7MxatQoREVFSa+9/x6LMmazGStWrMDjjz+O6OhoTJw4Ef/973+ttunRowdmzZpV4bXl9/mg2iq7x6KkpARLly5FYmIiOnbsiD59+mDLli0VzmyEh4dj4cKFOHToEJ588kl07NgRSUlJ+O6776p72yUFBQWYPXs24uPjERERgaeeegp79uyR1pfdb5Kbm4tvv/1Wqj03N7fS/V2/fh0A0KlTpwrrVCoVGjduDOBuvsuWLQMA9OzZ02q/o0ePrvSSJADo06cPxo8fX+2Ybt26hddffx3x8fHS+/Hpp58+8L149NFHAdxtJMrodDqcO3cOvXv3RosWLazWFRYW4tq1a9Lranrsqu6xOHjwIPr164eIiAg8+eST+Oqrr6q9/+bjjz9Gr1690LFjRwwePBhnz56V1s2aNQs7duwAAKvLEImo4eIZCyKiGhgwYABWrFiB77//HsOGDat0m0uXLuHFF19EeHg4pk6dCrVajZ9++kn6oBcWFoapU6di9erVGD58uPRhr/wH3F9//RUvvPACkpKS8NRTTyEgIKDautavXw+FQoEXXngBBQUF+PDDDzF27Fh8/vnn0pmVmqhJbeVZLBZMmjRJakjat2+P9PR0LFu2DLdu3cLs2bOttj916hT++c9/YuTIkfDx8cH27dsxdepU/Otf/5I+yFemtLQUY8aMwc8//4xRo0YhNDQUX375JWbNmoWioiI8++yzCAsLw7Jly5CSkoJmzZph3LhxAIAmTZpUus/mzZsDAPbv349OnTpVedbpiSeewLVr1/DFF1/g9ddfl+ps0qQJBgwYgLlz5+LixYto27at9JqzZ8/i2rVrmDRpUpVjys/Px7Bhw6BQKDBq1Cg0adIE3333HebMmQONRoOxY8dW+doWLVogODjYqnkou/wpJiYGMTExOH36NJ577jkA9xqQshxtOfa3336LV199FW3btsX06dNx584dzJkzB02bNq10+y+++ALFxcUYPnw4FAoFNm/ejJdffhmHDh2Cu7s7hg8fjtu3b+OHH36QGjgiatjYWBAR1UCzZs3g5+cn/ba7Mj/88AMMBgM2bdpU6YfawMBAdOvWDatXr0Z0dHSlNxfn5eVhwYIFGDFiRI3qunPnDtLS0qTLXDp06IBp06Zh165dSE5OruHoalZbeV9//TWOHj2KadOmSR+iR40ahalTpyI1NRWjR4/G73//e2n7y5cvIy0tTVrWpUsXDBgwAAcOHKj0huMyH3/8MS5fvox33nlHOkMwYsQIjBkzBitXrsTgwYMRGBiIAQMGYNWqVWjatOkDa4+OjsZjjz2GXbt24ZtvvsEf//hHdOrUCd27d5eaDgBo164dOnTogC+++AK9evVCaGiotK5v375YtGgR9u3bhxkzZkjL9+3bB29vb/Tu3bvK47/33nswmUzYv3+/1Kw888wz+POf/4y1a9dixIgR1TaFnTp1wrfffivdS3H69GmEhoYiODgYMTExWLt2rbTtqVOnANw702HLsd999100bdoUH330EXx8fADcPZs3ZswYhISEVNj+5s2b+Oc//wl/f38AQKtWrTB58mR8//336N69O2JiYvDwww/jhx9+eGBmRNQw8FIoIqIa8vb2RnFxcZXry27u/frrr2E2m+t0DLVajUGDBtV4+6efftrq2vm+ffsiKCgIhw8frtPxa+q7776DSqWqcHnWc889B4vFUuEyp/j4eKtGo127dvD19a22USs7TlBQEJ588klpmbu7O8aMGYOSkhKcOHGi1rUrFAps2bIF06ZNQ6NGjfDFF19g4cKF6N69O6ZNm1ajeyz8/PzQs2dPHDhwQLr0y2Qy4eDBg+jZsye8vb0rfZ3FYsE///lP9OjRAxaLBYWFhdKfhIQE/Pbbbzh37ly1x3700UdRWloqbXf69GnExMQAuNt0FBQU4Nq1awDu3nweGhqKpk2b2nTsW7du4eLFi3j66aelpgIAHnvsMaszNuX169dPaioAIDY2FgAemDkRNVw8Y0FEVEMlJSXVXprUr18/fPLJJ5g7dy7effddxMXF4YknnkDfvn2hVNbs9zhNmzat1Y3aLVu2tPpaoVCgZcuWuHHjRo33URc3btxAcHBwhRuCy2ZTuv/4Dz30UIV9+Pv7P/BD/I0bN9CyZcsK71/ZcW7evFnr2oG7DdykSZMwadIk3L59GydOnEBqaioOHjwINzc3LF++/IH7ePrpp5GWloaTJ0+ic+fOOHLkCPLz86v97XthYSGKiorw8ccf4+OPP65ym+qUv88iKioKmZmZeOWVVwAAbdu2ha+vL06fPo2HHnoI2dnZ6Nevn83HLnufyzeHZVq2bIn//Oc/FZbfn3lZkyHnm+OJyDZsLIiIauB///sffvvtt0o/WJXx9PTEjh07cOzYMXz77bdIT09HWloaPv74Y2zduhUqleqBx6nNfRG2MplMNarJHqo6jhymsA0ODkZSUhJ69+6NJ598El9++SWWLl36wBm/EhISEBgYiH379qFz587Yt28fgoKCEB8fX+Vrys5kPfXUUxg4cGCl2zzoBuZ27drBx8cHp06dQmJiIn799VfpHgqlUomoqCicOnUKv//972EwGKRGxB7Hrg05Z05E9YONBRFRDXz++ecA7n6YrI5SqURcXBzi4uLw+uuvY8OGDXjvvfdw7NgxxMfHQ6FQ2LWun376yepri8WCn376yeoDYlVnBm7evIkWLVpIX9emtpCQEGRkZECj0Vidtbhy5Yq03h5CQkJw4cIFmM1mq7MWZccpf0+Erdzd3REeHo5r167hl19+QVBQULXviUqlwpNPPok9e/ZgxowZOHToEIYNG1Zts9akSRP4+PjAbDZX24BUp+yZFKdPn8apU6fg6+trdTlSTEwM0tLSpLNZZY2FLccue59//vnnCuvu/x6sDXv/eyAi5+I9FkRED5CRkYG//vWvCA0NrXKKUeDujE73K3vQnF6vBwB4eXkBsN/lIHv37rV6KviXX36JvLw8dOvWTVrWokULnDlzRqoBAP71r39VmJa2NrV169YNJpNJmi60zAcffACFQmF1fFt069YNeXl5SEtLk5YZjUZs374d3t7e6Ny5c633ee3atUovoSoqKkJmZib8/f2lm+/L3pPffvut0n0NGDAAd+7cwbx581BSUlLt9wdwtyno06cP/vGPf+DixYsV1j/oMqgynTp1QmFhIXbv3o2oqCirpismJgZXr17F119/jd/97nfSZWO2HLtp06Zo27Yt9u7da3Wf0fHjxyvdV03Z+98DETkXz1gQEZXz3Xff4cqVKzCZTMjPz8exY8fwww8/oHnz5li/fn21Dw1bt24dTp48icTERISEhKCgoAB///vf0axZM+m3xr///e/RqFEj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5g899BC2bNmClJQUPPXUU2jatCmSk5PxwgsvOGsIVEu1zXzSpElQKBRYuXIlbt26hSZNmqB79+549dVXnTUEqqXs7GwkJydLX6ekpAAABg4ciKVLlyIvLw///e9/pfUtWrTAxo0bkZKSgtTUVDRr1gyLFy9G165dHV77/RQWnicjIiIiIiIb8VdbRERERERkMzYWRERERERkMzYWRERERERkMzYWRERERERkMzYWRERERERkMzYWRERERERkMzYWRERERERkMzYWRERERERkMzYWRETkcMeOHUN4eDiKioqcXUoF4eHhOHToUI23l/NYiIgciY0FERFVqbCwEPPnz8ef/vQndOzYEY8//jjGjx+PU6dOSdvU9oO4PVy+fBnh4eHIysqyWj5s2DBERERAp9NJy3Q6HSIiIvDJJ5/UaN/ff/89unXrZs9ysWbNGgwYMMCu+yQikhs3ZxdARETy9fLLL8NgMGDp0qVo0aIFCgoKkJGRgV9//dWpdYWFhSEoKAjHjx9HdHQ0AECj0eA///kPAgICkJWVhS5dugAAMjMzodfr8cc//rFG+w4KCqqvsomIXBrPWBARUaWKiopw8uRJzJgxA3/84x8REhKCyMhIvPjii+jZsycAoEePHgCAKVOmIDw8HD169EBubi7atWuHf//731b7++CDD9C9e3eYzeZKj3fy5EmMHDkSkZGRSExMxOLFi1FSUlJlfV26dMGxY8ekr0+dOoWHH34Y3bt3x/Hjx6Xlx48fR0hICFq0aAEAOHToEAYOHIiIiAj07NkTa9euhdFolLa//wzM6dOnMWDAAERERGDQoEE4dOgQwsPDkZOTY1XPuXPnMGjQIERFRWHEiBG4cuUKAGD37t1Yu3Ytzp8/j/DwcISHh2P37t1Vv/FERA0UGwsiIqqUt7c3vL29cejQIej1+kq3+fTTTwEAKSkp+P777/Hpp58iNDQU8fHxFT487969GwMHDoRSWfFHz88//4wXXngBvXv3xr59+/Dee+/h1KlTWLRoUZX1denSBadPn5aagmPHjuGxxx7DY489ZtVwHDt2TDp7cfLkSbz22mtITk5GWloaFi5ciN27d2PDhg2VHkOj0WDSpElo27Yt9uzZg1deeQXvvPNOpdu+9957mDVrFj777DOoVCrMnj0bANCvXz8899xzaNOmDb7//nt8//336NevX5XjIiJqqNhYEBFRpdzc3LB06VLs3bsXsbGxGDFiBFasWIHz589L2zRp0gQA0KhRIwQFBUlfDxkyBAcOHJAaknPnzuHixYsYNGhQpcfauHEj+vfvj7Fjx+Lhhx9Gp06dMGfOHOzdu9fqfonyunTpgpKSEunMyPHjx9G5c2fExsbizJkz0Ol0KC0txdmzZ6XGYu3atZgwYQIGDhyIFi1a4PHHH8crr7yCnTt3VnqM/fv3AwAWL16M1q1bIzExEc8//3yl27766qt47LHH0Lp1a0yYMAGZmZnQ6XTw9PSEt7c3VCoVgoKCEBQUBE9Pz2rfeyKihoj3WBARUZX69OmDP/3pTzh58iSysrKQnp6OzZs3Y/HixVU2CQDQq1cvLFy4EF999RWSkpKwZ88edOnSBaGhoZVuf/78eVy4cEH6IA8AFosFZrMZubm5CAsLq/Cali1bolmzZjh+/DjatGmDnJwcPPbYYwgICEDz5s2RmZkJi8UCvV4vNRbnz5/H6dOnrc5QmEwm6HQ6aLVaeHl5WR3j6tWrCA8Ph4eHh7QsIiKi0jGEh4dLfy+7T6OgoADNmzev8n0iInIlbCyIiKhaHh4eePzxx/H4449jypQpmDNnDtasWVNtY6FWq/H0009j9+7deOKJJ7B//37MmTOnyu1LSkowYsQIjBkzpsK6hx56qMrXlV32FB4ejpYtWyIgIAAA0LlzZxw7dgwWiwUtW7aU9lFSUoKXX34ZvXv3rnSctnBzu/cjVaFQAECV95MQEbkiNhZERFQrrVu3trq52d3dHSaTqcJ2Q4cOxZNPPom///3vMJlMlX6YL9OhQwf8+OOPaNmyZa1q6dKlC9566y2EhYXhsccek5bHxsbik08+gcVikc5WlB3n6tWrNT5Oq1atsG/fPuj1eqjVagCocFN6Tbi7u7PJICKXx3ssiIioUr/88guSk5Px+eef4/z587h+/ToOHjyIzZs3S7NCAUBISAgyMjKQl5eHO3fuSMvDwsIQFRWF5cuXIykpqdr7Cl544QVkZmZi4cKFyMnJwbVr13Do0CEsXLiw2hrL7rP47LPPrBqLxx57DGfOnLG6vwK4O3vV559/jrVr1+LSpUu4fPkyDhw4gPfee6/S/ffv3x8WiwVvvPEGLl++jPT0dGzduhXAvbMSNRESEoLc3Fzk5OSgsLCwypvhiYgaMjYWRERUKR8fH0RFReHDDz/E6NGj0b9/f6xatQpDhw7FvHnzpO1ee+01HDlyBH/6058wcOBAq30MGTIEBoMBgwcPrvZY7dq1w/bt23Ht2jWMHDkSAwcOxOrVqxEcHFzt61q0aIGQkBAUFxejc+fO0vLmzZsjODgYBoPBquHo2rUrNmzYgO+//x5DhgzBsGHD8MEHHyAkJKTS/fv6+mL9+vXIycnBgAED8N5772HKlCkAIJ3BqIk+ffqga9euSE5ORlxcHL744osav5aIqKFQWCwWi7OLICIi17Ru3Tp8+eWXVjdlN3T79u3D7NmzcfLkSc7uRERUDu+xICIiuysuLsaNGzewY8cOTJs2zdnl2GTv3r0IDQ1F06ZNceHCBSxfvhx9+/ZlU0FEdB82FkREZHeLFi3CF198gV69ej3wMii5y8vLw+rVq5GXl4egoCD07dsXr776qrPLIiKSHV4KRURERERENuPN20REREREZDM2FkREREREZDM2FkREREREZDM2FkREREREZDM2FkREREREZDM2FkREREREZDM2FkREREREZDM2FkREREREZDM2FkREREREZLP/B1VCAOKFXOSiAAAAAElFTkSuQmCC",
      "text/plain": [
       "<Figure size 800x500 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure(figsize=(8, 5))\n",
    "df_total[\"style_weight\"].hist(bins=np.linspace(0, 1, 100), color=\"skyblue\", edgecolor=\"black\")\n",
    "print_percentiles(df_total[\"style_weight\"])\n",
    "plt.title(\"Distribution of Style Weight\")\n",
    "plt.xlabel(\"Style Weight\")\n",
    "plt.ylabel(\"Counts\")\n",
    "plt.grid(True, linestyle=\"--\", alpha=0.6)\n",
    "plt.tight_layout()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 90,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-09-19T02:45:07.974201Z",
     "iopub.status.busy": "2025-09-19T02:45:07.974033Z",
     "iopub.status.idle": "2025-09-19T02:45:08.258682Z",
     "shell.execute_reply": "2025-09-19T02:45:08.258064Z",
     "shell.execute_reply.started": "2025-09-19T02:45:07.974184Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Percentiles:\n",
      "    5%: 0.0000\n",
      "   10%: 0.0000\n",
      "   20%: 0.1000\n",
      "   25%: 0.1500\n",
      "   50%: 0.4000\n",
      "   75%: 0.6600\n",
      "   80%: 0.7000\n",
      "   90%: 0.7600\n",
      "   95%: 0.8000\n"
     ]
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAxYAAAHqCAYAAACZcdjsAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8hTgPZAAAACXBIWXMAAA9hAAAPYQGoP6dpAABkL0lEQVR4nO3deXhTZf7//1eb7i2i7AqoCFJwWFpAGWqRERlBER1QcWFxwQVccMFBRAbZpIjIsCqIiIIooizKR9QRRhRlUxb5gogIoiwOdhGwa9okvz/8NRK60DZpkpP7+bgur8uenCTvO6+m5J1z7vuEuVwulwAAAADAC+GBLgAAAACA9dFYAAAAAPAajQUAAAAAr9FYAAAAAPAajQUAAAAAr9FYAAAAAPAajQUAAAAAr9FYAAAAAPAajQUAAAAAr9FYAEA1mjlzphITE/3yXAMGDNCAAQPcP2/evFmJiYn66KOP/PL8I0aMUNeuXf3yXFWVk5Ojp59+WpdffrkSExP17LPPBrSew4cPKzExUcuXL/fqcRITEzVz5kwfVQUAVUNjAQAVtHz5ciUmJrr/a926tVJTUzVo0CAtXLhQ2dnZPnmeY8eOaebMmdqzZ49PHs+Xgrm2ipg7d65WrFih2267TZMnT9YNN9xQ6n7XXnutrr/++hLbP/nkEyUmJqp///4lbnv33XeVmJioL774wud1A4AVRAS6AACwmqFDh6pRo0YqKipSRkaGtmzZookTJ+q1117Tiy++qBYtWrj3HTJkiO67775KPf6vv/6qWbNmqWHDhmrZsmWF7zd//vxKPU9VlFfb+PHj5XK5qr0Gb2zatElt27bVQw89VO5+7du317vvvqvff/9dNWrUcG/ftm2bIiIi9P/+3/9TYWGhIiMjPW6z2WxKSkqqcD0NGzbUzp07FRHBP8cArI8jFgBQSVdccYVuuOEG3Xjjjbr//vs1f/58LViwQJmZmXrggQeUn5/v3jciIkLR0dHVWk9eXp4kKSoqSlFRUdX6XOWJjIwM6PNXRGZmps4666wz7te+fXs5nU5t27bNY/u2bdvUo0cP5efna/fu3R63bd26VYmJiUpISKhwPWFhYYqOjpbNZit3v9zc3Ao/JgAECo0FAPhAp06d9MADD+jIkSN6//333dtLm2Px5Zdf6rbbblOHDh2UnJys7t27a+rUqZL+mBdx0003SZKeeuop92lXxefgDxgwQNddd5127dqlfv36qW3btu77nj7HopjT6dTUqVN1+eWXKykpSYMHD9Yvv/zisU/Xrl01YsSIEvc99THPVFtpcyxyc3M1adIkdenSRa1atVL37t01f/78Ekc2EhMTNW7cOK1Zs0bXXXedWrVqpZ49e+rzzz8v72V3y8zM1MiRI5WSkqLWrVvr+uuv14oVK9y3F883OXz4sNatW+eu/fDhw6U+Xvv27SXJo7EoKCjQ7t27dfXVV6tx48Yet2VlZengwYPu+0l/nDb21FNPKSUlxT2ed9991+N5SptjMWLECCUnJ+vnn3/Wvffeq+TkZD3xxBOSJLvdrokTJ+qvf/2rkpOTNXjwYP3vf/8rUX/x791PP/2kESNGqEOHDmrfvr2eeuopdyN6qvfee099+vRRmzZtdNlll+mxxx4r8Tty8OBBPfzww7r88svVunVrXXHFFXrsscf0+++/u/cp73cbQOjj2CsA+MgNN9ygqVOn6osvvlDfvn1L3Wffvn26//77lZiYqKFDhyoqKko//fST+0Nq06ZNNXToUM2YMUO33HKL+4Nqu3bt3I9x/Phx3XvvverZs6euv/561a5du9y6XnrpJYWFhenee+9VZmamXn/9dd1555167733FBMTU+HxVaS2U7lcLg0ZMsTdkLRs2VLr16/X5MmTdezYMY0cOdJj/61bt+o///mPbr/9dsXHx2vRokUaOnSoPv30U51zzjll1pWfn68BAwbo559/Vr9+/dSoUSN99NFHGjFihE6ePKk77rhDTZs21eTJk5WWlqYGDRrorrvukiTVqlWr1Mds3Lix6tWr59E8FJ/+lJycrOTkZG3btk133323pD8bkOLXIiMjQ3379lVYWJj69eunWrVq6fPPP9fTTz+t7Oxs3XnnneW+1kVFRRo0aJDat2+vJ5980p3T008/rffff1/XXXed2rVrp02bNpV7qt2jjz6qRo0a6fHHH9e3336rd955R7Vq1dI///lP9z4vvfSSpk+frmuuuUY33XSTsrKy9MYbb6hfv35auXKlzjrrLNntdg0aNEh2u139+/dXnTp1dOzYMa1bt04nT55UjRo1zvi7DSD00VgAgI80aNBANWrU0KFDh8rc58svv1RhYaHmzZtX6ofaOnXq6IorrtCMGTOUlJRU6uTi9PR0jR07VrfeemuF6jpx4oRWr17tPkXnkksu0aOPPqqlS5dq4MCBFRxdxWo71dq1a7Vp0yY9+uijGjJkiCSpX79+Gjp0qBYuXKj+/fvr/PPPd++/f/9+rV692r2tY8eOuuGGG/TBBx+UOlm62Ntvv639+/fr+eefd0+4vvXWWzVgwABNmzZNN954o+rUqaMbbrhB06dPV/369c9Yu/RHk7Bu3Tr3XIpt27apUaNGqlevnpKTkzVr1iz3vlu3bpX055GOf//733I4HFq1apW7Kbrtttv0+OOPa9asWbr11lvLbersdrt69OihYcOGubd99913ev/993X77bfrmWeecb+ew4YN0969e0t9nJYtW2rixInun48fP653333X3VgcOXJEM2fO1KOPPqrBgwe797v66qvVu3dvvfnmmxo8eLD279+vw4cPa/r06erRo4d7v1PnqpzpdxtA6ONUKADwobi4OOXk5JR5e/H5/WvXrpXT6azSc0RFRalPnz4V3v8f//iHx3n/PXr0UN26dfXZZ59V6fkr6vPPP5fNZitxetbdd98tl8tV4jSnlJQUj0ajRYsWSkhIKLdRK36eunXr6rrrrnNvi4yM1IABA5Sbm6uvvvqqSvW3b9/eYy7Ftm3blJycLOmPpiMzM1MHDx6UJG3fvl2NGjVS/fr15XK59J///Eddu3aVy+VSVlaW+7/U1FT9/vvvJeZnlOa2227z+Lk4r9NfzzvuuKPMxzi9+ezQoYOOHz/uXsHsk08+kdPp1DXXXONRZ506dXTBBRdo8+bNkuT+/fniiy9KPZVK8s3vNgBr44gFAPhQbm5uuacmXXvttXrnnXc0atQovfDCC+rUqZP+/ve/q0ePHgoPr9h3PfXr16/UJOkLLrjA4+ewsDBdcMEFOnLkSIUfoyqOHDmievXqlZjM3LRpU/ftpzr33HNLPEbNmjV18uTJMz7PBRdcUOL1K36eo0ePVrp2yXOeRdu2bbV9+3Y98sgjkqTmzZsrISFB27Zt07nnnqtdu3bp2muvlfTHfIuTJ0/q7bff1ttvv13qY2dlZZX73BEREWrQoIHHtiNHjig8PNyj+ZKkiy66qMzHOe+88zx+Lv7wf+LECSUkJOjgwYNyuVy6+uqry6xD+uPUsLvuuksLFizQqlWr1KFDB3Xt2lXXX3+9e9UsX/xuA7A2GgsA8JH//e9/+v3330t88DtVTEyMFi9erM2bN2vdunVav369Vq9erbfffluvvvrqGVcHKn4Mf3E4HBWqyRfKep5ALWHbokULxcfHa+vWrerSpYuOHz/unkMRHh6utm3bauvWrTr//PNVWFjobkSKv62//vrr1bt371If+0wXTYyKivLJh/GyHqP4NXU6nQoLC9O8efNKff3j4uLc/z9ixAj17t1ba9eu1ZdffqkJEyZo7ty5Wrp0qRo0aOCT320A1kZjAQA+8t5770mSUlNTy90vPDxcnTp1UqdOnfTUU09pzpw5+ve//63NmzcrJSVFYWFhPq3rp59+8vjZ5XLpp59+8vhwW9aRgaNHj6px48bunytTW8OGDbVx40ZlZ2d7HLU4cOCA+3ZfaNiwofbu3Sun0+nxQbr4eU7/1r6iiq9JsW3bNm3dulUJCQlq3ry5+/bk5GStXr3afUSouLGoVauW4uPj5XQ6lZKSUtVhldCwYUM5nU79/PPPHkcpisdZFeeff75cLpcaNWqkJk2anHH/4tW0HnjgAW3btk233Xab3nrrLT322GOSzvy7DSC0cWwSAHxg48aNevHFF9WoUaNSr9hc7Pjx4yW2FV9ozm63S5JiY2Ml6YynAFXUypUrPa4K/tFHHyk9PV1XXHGFe1vjxo31zTffuGuQpE8//bTEkqOVqe2KK66Qw+HQ4sWLPba/9tprCgsL83h+b1xxxRVKT0/X6tWr3duKioq0aNEixcXF6dJLL63yY7dr105ZWVlavny52rZt69G4JCcn68cff9TatWt19tlnu0+9stls6t69uz7++GN9//33JR7zTKdBlaX49Vq0aJHH9tdff71Kjyf9MUnbZrNp1qxZJY4MuVwu/fbbb5Kk7OxsFRUVedzevHlzhYeHu39nKvK7DSC0ccQCACrp888/14EDB+RwOJSRkaHNmzfryy+/1HnnnaeXXnqp3AvizZ49W19//bW6dOmihg0bKjMzU2+++aYaNGjg/sb7/PPP11lnnaUlS5YoPj5ecXFxatOmjceRg8qoWbOmbr/9dvXp08e93OwFF1zgsSTuzTffrI8//lj33HOPrrnmGv38889atWpVidO6KlNb165d1bFjR/373//WkSNHlJiYqC+//FJr167VHXfcUe4pY5Vxyy236O2339aIESO0e/duNWzYUB9//LG2bdumkSNHVuqCdacrzmT79u16+OGHPW5L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rt27d+v+++93bwsPD1dKSoq2b98ewMoAwGzM1wCqR3VeEFQq+7pQZ7pelC+uPVXW9qrcx1ePFQqncdJYVNBvv/0mh8NR4pSn2rVr68CBA5V6rLAwX1ZWMTabTTVq1NDvRw4qM8Lm3l6QdazU7eXdVtntPBaPZfV6eSx+V3is4H8sq9UbSo91/Kd9SoiP1xV3PKSzGzT0eKz/7f9OXy1fpMGD79bpylp6urwlqUt7/v99u11n1ayp4cMf98lzVPY+vnyssjL5/chB1ahRQzabze+fIyvzfGEul8tVfaWEjmPHjumKK67QkiVLlJyc7N4+efJkffXVV3rnnXcCWB0AAAAQWOGBLsAqzjnnHNlsNmVmeq5EkJmZqTp16gSoKgAAACA40FhUUFRUlP7yl79o48aN7m1Op1MbN270OIIBAAAAmIg5FpVw11136cknn1SrVq3Upk0bvf7668rLy1OfPn0CXRoAAAAQUDQWlXDttdcqKytLM2bMUHp6ulq2bKlXXnmFU6EAAABgPCZvAwAAAPAacywAAAAAeI3GAgAAAIDXaCwAAAAAeI3GAgAAAIDXaCxCyOLFi9W1a1e1bt1aN998s3bu3Fnu/h9++KF69Oih1q1bq1evXvrss8/8VCl8pTKZL126VLfffrsuvfRSXXrppbrzzjvP+DuC4FPZ93mxDz74QImJiXrggQequUL4WmUzP3nypMaOHavU1FS1atVK3bt35++7xVQ289dee03du3dXmzZt1KVLF02cOFEFBQV+qhbe+uqrrzR48GClpqYqMTFRa9asOeN9Nm/erN69e6tVq1b6+9//ruXLl/uh0jOjsQgRq1evVlpamh588EGtWLFCLVq00KBBg0pcKbzYtm3bNGzYMN10001auXKlrrrqKj344IP6/vvv/Vw5qqqymW/evFk9e/bUwoULtWTJEp177rm6++67dezYMT9XjqqqbObFDh8+rOeee04dOnTwU6Xwlcpmbrfbddddd+nIkSOaPn26PvroI40fP17169f3c+WoqspmvmrVKr3wwgt66KGHtHr1aj377LNavXq1pk6d6ufKUVW5ublKTEzUM888U6H9Dx06pPvvv18dO3bUe++9pzvuuEOjRo3S+vXrq7nSCnAhJNx0002usWPHun92OByu1NRU19y5c0vd/5FHHnHdd999Httuvvlm17/+9a9qrRO+U9nMT1dUVORKTk52rVixopoqhK9VJfOioiLXLbfc4lq6dKnrySefdA0ZMsQfpcJHKpv5m2++6brqqqtcdrvdXyXCxyqb+dixY10DBw702JaWlua69dZbq7VOVI/mzZu7Pvnkk3L3mTx5sqtnz54e2x599FHX3XffXZ2lVQhHLEKA3W7X7t27lZKS4t4WHh6ulJQUbd++vdT77NixQ506dfLYlpqaqh07dlRnqfCRqmR+ury8PBUVFalmzZrVVSZ8qKqZz549W7Vr19bNN9/sjzLhQ1XJ/L///a+SkpI0btw4paSk6LrrrtOcOXPkcDj8VTa8UJXMk5OTtXv3bvfpUocOHdJnn32mLl26+KVm+F8wf4bjytsh4LfffpPD4VDt2rU9tteuXVsHDhwo9T4ZGRklrhheu3ZtZWRkVFud8J2qZH66KVOmqF69eh7/gCF4VSXzr7/+Wu+++65Wrlzphwrha1XJ/NChQ9q0aZN69eqll19+WT///LPGjh2roqIiPfTQQ/4oG16oSua9evXSb7/9pttvv10ul0tFRUW69dZbNXjwYH+UjAAo7TNcnTp1lJ2drfz8fMXExASoMuZYAEZ6+eWXtXr1as2aNUvR0dGBLgfVIDs7W8OHD9f48eNVq1atQJcDP3G5XKpdu7bGjx+vVq1a6dprr9XgwYO1ZMmSQJeGarJ582bNnTtXzzzzjJYvX65Zs2bps88+0+zZswNdGgzEEYsQcM4558hms5WY2JWZmVmioy1Wp06dEkcnytsfwaUqmRebP3++Xn75ZS1YsEAtWrSozjLhQ5XN/NChQzpy5IiGDBni3uZ0OiVJl1xyiT766COdf/751Vs0vFKV93ndunUVEREhm83m3nbRRRcpPT1ddrtdUVFR1VozvFOVzKdPn67rr7/efbpjYmKicnNzNXr0aA0ZMkTh4XyHHGpK+wyXkZGhhISEgB6tkDhiERKioqL0l7/8RRs3bnRvczqd2rhxo5KTk0u9T1JSkjZt2uSxbcOGDUpKSqrOUuEjVclckubNm6cXX3xRr7zyilq3bu2PUuEjlc38oosu0qpVq7Ry5Ur3f127dlXHjh21cuVKNWjQwJ/lowqq8j5v166dfv75Z3cTKUkHDx5U3bp1aSosoCqZ5+fnl2geihtLl8tVfcUiYIL5MxyNRYi46667tHTpUq1YsUL79+/XmDFjlJeXpz59+kiShg8frhdeeMG9/8CBA7V+/Xq9+uqr2r9/v2bOnKldu3apf//+gRoCKqmymb/88suaPn26Jk6cqIYNGyo9PV3p6enKyckJ1BBQSZXJPDo6Ws2bN/f476yzzlJ8fLyaN2/Oh0yLqOz7/LbbbtPx48f17LPP6scff9S6des0d+5c9evXL1BDQCVVNvMrr7xSb731lj744AMdOnRIX375paZPn64rr7zS48gVgldOTo727NmjPXv2SPpjifA9e/bo6NGjkqQXXnhBw4cPd+9/66236tChQ5o8ebL279+vxYsX68MPP9Sdd94ZiPI9cCpUiLj22muVlZWlGTNmKD09XS1bttQrr7ziPnT6yy+/eHyj0a5dO02ZMkXTpk3T1KlTdeGFF2r27Nlq3rx5oIaASqps5kuWLFFhYaGGDh3q8TgPPfSQHn74Yb/WjqqpbOawvspmfu6552r+/PlKS0vT9ddfr/r162vgwIG69957AzUEVFJlMx8yZIjCwsI0bdo0HTt2TLVq1dKVV16pxx57LFBDQCXt2rVLAwcOdP+clpYmSerdu7cmTZqk9PR0/fLLL+7bGzdurLlz5yotLU0LFy5UgwYNNGHCBHXu3NnvtZ8uzMVxMgAAAABe4qstAAAAAF6jsQAAAADgNRoLAAAAAF6jsQAAAADgNRoLAAAAAF6jsQAAAADgNRoLAAAAAF6jsQAAAADgNRoLADBQ165d9dprr1X6fjNnztQNN9zg+4JQrs2bNysxMVEnT54MdCkAUCYaCwAw0Lvvvqtbbrkl0GWErMOHDysxMVF79uzxyeMlJyfriy++UI0aNSp8nxEjRuiBBx7wyfMDQEXQWACAgWrVqqXY2Ngyby8sLPRjNeay2+0V2i8qKkp169ZVWFhYNVcEAFVHYwEAFvDpp5+qQ4cOcjgckqQ9e/YoMTFRU6ZMce/z9NNP64knnpAkff3117r99tvVpk0bdenSRRMmTFBubq5739NPhUpMTNSbb76pwYMHKykpSXPmzJEkvfzyy0pJSVFycrJGjhypgoICj7qKvxWfP3++UlNT1bFjR40dO9ajMbHb7XruuefUuXNnJSUl6eabb9bmzZvdtx85ckSDBw/WpZdeqqSkJPXs2VOfffaZJOnEiRMaNmyY/vrXv6pNmza6+uqrtWzZsgq9Zv/73//0+OOP67LLLlNSUpL69Omjb775xn37m2++qW7duqlVq1bq3r27Vq5c6XH/xMREvfPOO3rwwQfVtm1bXX311Vq7dq379vJqu+qqqyRJ//jHP5SYmKgBAwZ4vF4vvfSSUlNT1aNHD0nSypUr1adPHyUnJ+vyyy/XsGHDlJmZ6X6u00+FWr58uTp06KD169frmmuuUXJysgYNGqRff/1V0h+nrK1YsUJr165VYmKiEhMTPV5zAKgOEYEuAABwZh06dFBOTo6+/fZbtW7dWlu2bNE555yjLVu2uPf56quvdO+99+rnn3/Wvffeq0ceeUQTJ05UVlaWxo8fr/HjxystLa3M55g1a5aGDRump59+WjabTatXr9bMmTM1evRotW/fXu+9954WLVqkxo0be9xv8+bNqlu3rl5//XX9/PPPeuyxx9SyZUv17dtXkjRu3Dj98MMP+ve//6169erpk08+0T333KNVq1bpwgsv1Lhx41RYWKg33nhDcXFx+uGHHxQXFydJmj59uvbv36958+bpnHPO0c8//6z8/Pwzvl45OTnq37+/6tevrxdffFF169bV7t275XQ6JUmffPKJJk6cqKeeekopKSlat26dRo4cqQYNGuivf/2rx2vyz3/+U8OHD9eiRYv0xBNP6NNPP9XZZ59dbm3vvPOObr75Zr322mtq1qyZIiMj3Y+5ceNGJSQkaMGCBe5tRUVFeuSRR3TRRRcpMzNTkyZN0ogRIzRv3rwyx5ifn69XX31VkydPVnh4uP75z3/queee0wsvvKC7775b+/fvV3Z2tjvzmjVrnvF1AwBv0FgAgAXUqFFDLVu21JYtW9yNxZ133qlZs2YpJydH2dnZ+umnn3TppZdq7ty56tWrl+68805J0oUXXqinn35aAwYM0JgxYxQdHV3qc1x33XW68cYb3T8//vjjuummm3TzzTdLkh577DFt3LixxFGLmjVravTo0bLZbGratKm6dOmijRs3qm/fvjp69KiWL1+uTz/9VPXr15ckDRo0SOvXr9fy5cv1+OOP6+jRo+revbsSExMlyaNxOXr0qFq2bKnWrVtLkho1alSh1+v//u//lJWVpXfffVdnn322JOmCCy5w3z5//nz17t1b/fr1kyQ1adJEO3bs0KuvvurRWPTu3VvXXXed+/VYtGiRdu7cqSuuuKLc2mrVqiVJOvvss1W3bl2P2uLi4jRhwgRFRUW5t910003u/2/cuLGefvpp3XTTTcrJyVF8fHypYywsLNTYsWN1/vnnS5L69eunF198UZIUHx+vmJgY2e32Es8PANWFxgIALOLSSy/Vli1bdPfdd+vrr7/W448/rg8//FBbt27ViRMnVK9ePV144YX67rvvtHfvXq1atcp9X5fLJafTqcOHD6tp06alPn6rVq08ft6/f79uvfVWj21JSUklTqlp1qyZbDab++e6devq+++/lyR9//33cjgc7lN+itntdvcH/oEDB2rMmDH64osvlJKSoquvvlotWrSQJN12220aOnSovv32W11++eXq1q2b2rVrd8bXas+ePbrkkkvcz3G6AwcOlJi83q5dOy1cuNBjW3GzI/3RECQkJCgrK8ur2po3b+7RVEjSrl27NGvWLH333Xc6ceKEXC6XJOmXX35Rs2bNSn2c2NhYd1MhSfXq1fM4fQoA/I3GAgAs4rLLLtOyZcv03XffKTIyUk2bNtVll12mLVu26OTJk7rsssskSbm5ubr11lvd5/Wf6txzzy3z8YtPP6qsiAjPf0rCwsLcH4xzc3Nls9m0bNkyj+bj1Oe7+eablZqaqnXr1unLL7/Uyy+/rCeffFIDBgxQly5d9Omnn+qzzz7Tl19+qTvvvFP9+vXTk08+WW5NMTExVRrL6U49hal4bMWnU1W1ttMnzefm5mrQoEFKTU3VlClTdM455+iXX37RoEGDyp1EX97rDgCBwORtALCI4nkWr732mi699FJJUseOHbVlyxZt3rzZ3Vhccskl+uGHH3TBBReU+O/0b8rL07RpU4/JzpJK/HwmLVu2lMPhUFZWVolaTj1F59xzz9Vtt92mWbNm6a677tLSpUvdt9WqVUu9e/fWlClTNHLkSL399ttnfN7ipV6PHz9e6u0XXXSRtm3b5rFt27ZtZR4dKEtZtRU3JMWT7ctz4MABHT9+XE888YQ6dOigpk2b+uTIQ2RkpLsJAgB/oLEAAIuoWbOmEhMTtWrVKncT0aFDB3377bc6ePCgu9m49957tX37do0bN0579uzRwYMHtWbNGo0bN65Szzdw4EAtW7ZMy5Yt048//qgZM2Zo3759lXqMJk2aqFevXho+fLj+85//6NChQ9q5c6fmzp2rdevWSZKeffZZrV+/XocOHdLu3bu1efNm9+la06dP15o1a/TTTz9p3759WrduXZmncp2qZ8+eqlOnjh588EFt3bpVhw4d0scff6zt27dLku655x6tWLFCb775pg4ePKgFCxbok08+0d13313hsZVXW+3atRUTE6P169crIyNDv//+e5mPc9555ykyMlKLFi3SoUOHtHbtWvdcCW80bNhQe/fu1YEDB5SVlcUSwgCqHadCAYCFXHrppdqzZ4+7sTj77LPd33BfdNFFkqQWLVpo0aJFmjZtmm6//XZJf0wIvvbaayv1XNdee61+/vlnPf/88yooKFD37t1122236YsvvqjU46Slpemll17SpEmT9Ouvv+rss89WUlKS/va3v0mSnE6nxo0bp//9739KSEhQ586d9dRTT0n641v3qVOn6siRI4qJiVH79u01derUMz5nVFSUXn31VT333HO677775HA41LRpUz3zzDOSpG7dumnkyJF69dVXNXHiRDVs2FATJ05Ux44dKzyu8mqLiIjQqFGjNHv2bM2YMUMdOnTQokWLSn2cWrVqadKkSZo6daoWLVqkv/zlL3ryySc1ZMiQCtdSmr59+2rLli268cYblZubq4ULF1ZqfABQWWEuTsgEAAAA4CVOhQIAAADgNU6FAgBYzpw5czR37txSb2vfvr1eeeUVP1cEAOBUKACA5Rw/flwnTpwo9baYmBj3xfgAAP5DYwEAAADAa8yxAAAAAOA1GgsAAAAAXqOxAAAAAOA1GgsAAAAAXqOxAAAAAOA1GgsAAAAAXqOxAAAAAOA1GgsAAAAAXvv/ACFazvkHNfIdAAAAAElFTkSuQmCC",
      "text/plain": [
       "<Figure size 800x500 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure(figsize=(8, 5))\n",
    "df_total[\"weirdness_constraint\"].hist(bins=np.linspace(0, 1, 100), color=\"skyblue\", edgecolor=\"black\")\n",
    "print_percentiles(df_total[\"weirdness_constraint\"])\n",
    "plt.title(\"Distribution of Weirdness\")\n",
    "plt.xlabel(\"weirdness_constraint\")\n",
    "plt.ylabel(\"Counts\")\n",
    "plt.grid(True, linestyle=\"--\", alpha=0.6)\n",
    "plt.tight_layout()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 91,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-09-19T02:45:08.259571Z",
     "iopub.status.busy": "2025-09-19T02:45:08.259404Z",
     "iopub.status.idle": "2025-09-19T02:45:08.520139Z",
     "shell.execute_reply": "2025-09-19T02:45:08.519533Z",
     "shell.execute_reply.started": "2025-09-19T02:45:08.259555Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Percentiles:\n",
      "    5%: 0.1000\n",
      "   10%: 0.2000\n",
      "   20%: 0.4000\n",
      "   25%: 0.4700\n",
      "   50%: 0.7400\n",
      "   75%: 0.9500\n",
      "   80%: 1.0000\n",
      "   90%: 1.0000\n",
      "   95%: 1.0000\n"
     ]
    },
    {
     "data": {
      "image/png": "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V583APZDYwEA//X2229LktLT0ytdLzIyUqmpqUpNTdWf/vQnzZw5U3/5y1+0bt06paWllTlbG6rvvvsu6Ge/36/vvvsuaLaqiq4MHDx4UK1btw78XJ3aEhMTlZmZqby8vKCrFrt37w68Hg6JiYnavn27fD5f0Bn94/s5++yzq73NDz/8UB6PRy+++GLQ+8u75ae8353H41FWVlbQsrPPPrtMFpK0Z8+e09YTzjF26dJF0dHR2rhxozZu3KgRI0ZIki666CK99dZbWrt2rSQFNRbnnHOOMjMz1b1792o3tomJidq5c6f8fn/Q5+f777+v1nZOFu6/EQD2wDMWACApMzNTL7zwglq1ahV4uLY8hw8fLrPs+Bd8eTweSVJsbKwknfYWoKpavny58vLyAj+vWrVKWVlZ6t27d2BZ69at9dVXXwVqkKSPPvqozLS01amtd+/e8nq9WrhwYdDyefPmKSIiImj/oejdu7eysrK0cuXKwLLS0lItWLBAcXFxQTMbVdXxs+YnXy05evSolixZUmbd1q1bB82oJEmLFy8uc8WiT58+2rx5s7Zs2RJYlpubqxUrVpy2nnCOMSYmRp07d9bf/vY3HTx4MNBA9OjRQ0VFRZo/f77OOeccNW/ePPCeX/3qV/J6vXrhhRfKbK+0tLTSz0N6eroOHTqkDz74ILCsuLhYixcvrnLNpwr33wgAe+CKBQDjfPrpp9q9e7e8Xq+ys7O1bt06ff755zr77LP14osvVjp96PPPP68NGzaoT58+SkxMVE5Ojl5//XW1bNkyMG3mOeecozPOOEOLFi1Sw4YNFRcXpy5dugRdOaiOxo0b65ZbbtGgQYMC082ee+65QQ/PXn/99fr73/+uO+64Q7/61a/0/fffa8WKFWVu66pObX379lXPnj31l7/8RQcOHFBSUpI+//xzffDBB7r11lsrvWWsOm688Ua9+eabGjdunLZt26bExET9/e9/15dffqnx48dXabakU11yySWKjo7WyJEjddNNNyk/P19vvfWWEhISylyJuP766zVx4kTdd999SktL0zfffKPPPvuszBS5d9xxh95++23dcccdGjZsWGC62bPPPvu0zw+Ee4w9evTQSy+9pEaNGqlDhw6SpISEBLVp00Z79uwpMznAxRdfrBtvvFGzZs3S119/Hfj97N27V6tWrdKDDz6oK6+8ssLa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NBbZm4nczUX25iJ72BmNhYPk5zNThKnI3kzkbi6yNxfZw85oLBzE5SJOU5G9mcjdXGRvLrKHnfHpdJDY2GirS4BFyN5M5G4usjcX2cPOaCwAAAAAhIzGAgAAAEDIaCwcxOdjqghTkb2ZyN1cZG8usoed0Vg4SEGBx+oSYBGyNxO5m4vszUX2sDMaCweJinJZXQIsQvZmIndzkb25yB52RmPhIA0aRFldAixC9mYid3ORvbnIHnZGYwEAAAAgZDQWAAAAAEJGY+EgXq/P6hJgEbI3E7mbi+zNRfawM0sbC6/Xq+nTp6tv377q0qWL+vXrp+eff15+/4mp1Px+v5555hmlp6erS5cuuu2227R3796g7Rw+fFgPPPCAunfvrh49emj8+PHKz88PWuebb77RLbfcos6dO6tPnz6aPXt2mXree+89XXnllercubOuvvpqffLJJ7Uy7tpSWFhidQmwCNmbidzNRfbmInvYmaWNxezZs/XGG2/ooYce0sqVK/X73/9eL7/8shYsWBC0zoIFC/Twww9r8eLFio2N1YgRI1RcXBxY5/e//7127typuXPnaubMmdqwYYMeeuihwOt5eXkaMWKEzj77bC1dulRjx47Vc889pzfffDOwzpdffqkHHnhA1113nZYvX67LLrtM99xzj7799tu6+WWEgdvNTBGmInszkbu5yN5cZA87s7Sx2LRpky677DL94he/UKtWrXTllVcqPT1dW7ZskXTsasX8+fM1atQo9evXTx07dtQTTzyhH374Qe+//74kadeuXVq9erWmTJmirl27qkePHpowYYLeffddHTp0SJL0zjvvqKSkRFOnTlX79u3Vv39/DR06VHPnzg3UMn/+fPXq1Ut33HGH2rZtq/vvv1/nn3++Xnvttbr/xdSQ281MEaYiezORu7nI3lxkDzuztLFISUnR2rVrtWfPHknHblfauHGjevfuLUnav3+/srKylJaWFnhPo0aN1LVrV23atEnSsebkjDPOUOfOnQPrpKWlKTIyMtCgbN68WT169JDb7Q6sk56erj179uinn34KrJOamhpUX3p6ujZv3hz+gQMAAAAOY2nbe9dddykvL0+/+tWv5HK55PV69bvf/U4DBgyQJGVlZUmSEhISgt6XkJCg7OxsSVJ2draaNGkS9HpUVJQaN24ceH92drZatWoVtE7Tpk0DrzVu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64orruC/+fVUdbOfN2+errjiCnXp0kV9+vTR1KlTVVxcXEfVIhy++OILjRw5Uunp6UpKStL7779/2vesW7dOAwcOVHJysi6//HItXbq0Dio9PRqLemLlypXKyMjQPffco2XLlqljx44aMWJEmW8KP+7LL7/UAw88oOuuu07Lly/XZZddpnvuuUfffvttHVeOUFQ393Xr1ql///6aP3++Fi1apLPOOku33367Dh06VMeVI1TVzf64/fv36/HHH1ePHj3qqFKEW3Wz93g8Gj58uA4cOKBnnnlGq1at0uTJk9WiRYs6rhyhqm72K1as0NNPP617771XK1eu1KOPPqqVK1dq2rRpdVw5QlFQUKCkpCRNnDixSuvv27dPd999t3r27Km3335bt956qyZMmKDVq1fXcqVV4Ee9cN111/knTZoU+Nnr9frT09P9s2bNKnf93/72t/677roraNn111/v//Of/1yrdSK8qpv7qUpLS/0pKSn+ZcuW1VKFqC01yb60tNR/4403+hcvXuz/4x//6B81alRdlIowq272r7/+uv+yyy7zezyeuioRtaS62U+aNMk/bNiwoGUZGRn+m266qVbrRO3p0KGD/5///Gel6zzxxBP+/v37By27//77/bfffnttllYlXLGoBzwej7Zt26a0tLTAssjISKWlpWnTpk3lvmfz5s1KTU0NWpaenq7NmzfXZqkIo5rkfqrCwkKVlpaqcePGtVUmakFNs3/++eeVkJCg66+/vi7KRC2oSfYffvihunXrpkceeURpaWn69a9/rZkzZ8rr9dZV2QiDmmSfkpKibdu2BW6X2rdvnz755BP16dOnTmqGNex8jMc3b9cDP/74o7xerxISEoKWJyQkaPfu3eW+Jzs7u8w3hickJCg7O7vW6kR41ST3Uz311FNq3rx50P+oYH81yX7Dhg3661//quXLl9dBhagtNcl+3759Wrt2ra6++mq99NJL+v777zVp0iSVlpbq3nvvrYuyEQY1yf7qq6/Wjz/+qFtuuUV+v1+lpaW66aabNHLkyLooGRYp7xivadOmysvLU1FRkRo0aGBRZTxjATjWSy+9pJUrV+q5555TTEyM1eWgFuXl5Wns2LGaPHmymjRpYnU5qGN+v18JCQmaPHmykpOTddVVV2nkyJFatGiR1aWhlq1bt06zZs3SxIkTtXTpUj333HP65JNP9Pzzz1tdGgzFFYt64Mwzz5TL5Srz8FZOTk6ZjvW4pk2blrk6Udn6sJ+a5H7cnDlz9NJLL2nu3Lnq2LFjbZaJWlDd7Pft26cDBw5o1KhRgWU+n0+SdP7552vVqlU655xzardohEVN/u6bNWumqKgouVyuwLKf//znysrKksfjkdvtrtWaER41yf6ZZ57RgAEDArc/JiUlqaCgQA899JBGjRqlyEjOHztRecd42dnZio+Pt/RqhcQVi3rB7XbrggsuUGZmZmCZz+dTZmamUlJSyn1Pt27dtHbt2qBla9asUbdu3WqzVIRRTXKXpNmzZ+uFF17Qyy+/rM6dO9dFqQiz6mb/85//XCtWrNDy5csD//Tt21c9e/bU8uXL1bJly7osHyGoyd999+7d9f333weaSUnau3evmjVrRlNRj9Qk+6KiojLNw/EG0+/3116xsJSdj/FoLOqJ4cOHa/HixVq2bJl27dqlhx9+WIWFhRo0aJAkaezYsXr66acD6w8bNkyrV6/WK6+8ol27dunZZ5/V1q1bNWTIEKuGgBqobu4vvfSSnnnmGU2dOlWJiYnKyspSVlaW8vPzrRoCaqg62cfExKhDhw5B/5xxxhlq2LChOnTowMFlPVPdv/ubb75Zhw8f1qOPPqo9e/bo448/1qxZszR48GCrhoAaqm72l156qd544w29++672rdvnz7//HM988wzuvTSS4OuYMHe8vPz9fXXX+vrr7+WdGza8K+//loHDx6UJD399NMaO3ZsYP2bbrpJ+/bt0xNPPKFdu3Zp4cKFeu+993TbbbdZUX4QboWqJ6666irl5uZqxowZysrKUqdOnfTyyy8HLo/+5z//CTpr0b17dz311FOaPn26pk2bpvPOO0/PP/+8OnToYNUQUAPVzX3RokUqKSnRmDFjgrZz77336r777qvT2hGa6mYP56hu9meddZbmzJmjjIwMDRgwQC1atNCwYcN05513WjUE1FB1sx81apQiIiI0ffp0HTp0SE2aNNGll16q3/3ud1YNATWwdetWDRs2LPBzRkaGJGngwIF67LHHlJWVpf/85z+B11u3bq1Zs2YpIyND8+fPV8uWLTVlyhT16tWrzms/VYSfa2UAAAAAQsTpLgAAAAAho7EAAAAAEDIaCwAAAAAho7EAAAAAEDIaCwAAAAAho7EAAAAAEDIaCwAAAAAho7EAAAAAEDIaCwBArVi6dKl69OgR+PnZZ5/VNddcY2FFFVu3bp2SkpJ05MiRKr/HzuMBACvQWAAA6sTtt9+uefPmWV1GuVJSUvTZZ5+pUaNGYd3u0KFD9eijj4Z1mwBgV1FWFwAAMEPDhg3VsGFDq8sol9vtVrNmzawuAwDqNa5YAAD06aef6uabb1aPHj3Us2dP3X333fr+++8llX+b0Ndff62kpCTt378/sGzp0qX6xS9+oa5du+qee+7R4cOHg/Zx6q1DPp9Pzz33nHr37q3k5GRdc801+vTTT6tU75gxY/TII48Efn700UeVlJSkXbt2SZI8Ho+6deumNWvWBPY1a9Ys9e3bV126dNGAAQO0atWqwPvLG+PixYvVp0+fwHjmzp0bdGvXccuXL1ffvn114YUX6ne/+53y8vIkSePGjdP69es1f/58JSUllfl9AYDT0FgAAFRYWKjhw4dryZIlmjdvniIiInTPPffI5/NV6f1fffWVHnzwQQ0ePFjLly9Xz5499eKLL1b6nvnz52vu3Ln64x//qHfeeUfp6ekaPXq09u7de9r9XXTRRVq/fn3g5y+++EJnnnlmYNm//vUvlZaWKiUlRZI0a9YsLV++XJMmTdK7776r2267TX/4wx+CtnGyjRs3auLEiRo2bJiWL1+utLQ0zZw5s8x633//vT744APNnDlTs2bN0hdffKHZs2dLkh588EGlpKTohhtu0GeffabPPvtMZ5111mnHBgD1FbdCAQB0xRVXBP08depUpaamaufOnVV6//z589WrVy/deeedkqQ2bdpo06ZNWr16dYXvmTNnju688071799fkvSHP/xB69at06uvvqqJEydWur+LL75Yjz76qHJzc+VyubRz506NHj1a69ev180336z169crOTlZsbGx8ng8mjVrlubOnRtoNFq3bq2NGzfqzTff1MUXX1xm+6+99pp69+6tESNGBI3n448/DlrP7/crIyND8fHxkqQBAwYoMzNTv/vd79SoUSNFR0erQYMG3GYFwAg0FgAA7d27VzNmzNBXX32lH3/8UX6/X5L0n//8Rw0aNDjt+3ft2qV+/foFLevWrVuFjUVeXp5++OEHde/ePWh59+7d9c0335x2fx06dFDjxo21fv16RUdH6/zzz9ell16q119/XdKxKxg9e/aUJH333XcqLCzU7bffHrSNkpISderUqdzt79mzp8x4unTpUqaxSExMDDQVktS8eXPl5OSctn4AcCIaCwCARo4cqcTERE2ZMkXNmzeXz+fTr3/9a5WUlCguLk6SAs2GdOyg3EoRERGB26HcbrcuvvhiJSUlyePx6Ntvv9WmTZsCjURBQYGkY7dDtWjRImg7brc7pDqiosr+b/Tk3xMAmIRnLADAcD/++KP27NmjUaNGKTU1VW3bttVPP/0UeL1JkyaSpKysrMCyU68qtG3bVlu2bAla9tVXX1W4z/j4eDVv3lxffvll0PIvv/xS7dq1q1LdxxuL9evX6+KLL1ZkZKR69OihOXPmyOPxBK6GtG3bVm63WwcPHtS5554b9E9Fzzy0adNGW7duDVr2r3/9q0p1nSw6OrrKz6kAQH1HYwEAhmvcuLF+9rOf6c0339R3332nzMxMPfbYY4HXzznnHJ111ll69tlntXfvXn388cd65ZVXgrYxdOhQrV69WnPmzNHevXv12muvVfp8hSSNGDFCs2fP1sqVK7V792499dRT+uabbzRs2LAq1d2zZ0/t3LlTO3bs0IUXXijp2LMXK1asUHJycuBKS3x8vG6//XZlZGRo2bJl+v7777Vt2zYtWLBAy5YtK3fbQ4YM0SeffKK5c+dq7969WrRokT799FNFRERUqbbjEhMT9dVXX2n//v3Kzc2lyQDgaDQWAGC4yMhI/eUvf9G2bdv061//WhkZGRo7dmzg9ejoaD399NPavXu3BgwYoNmzZ+v+++8P2ka3bt00efJkzZ8/X9dcc40+++wzjRo1qtL9Dhs2TMOHD9djjz2mAQMGaPXq1XrhhRd03nnnVanuDh066IwzzlCnTp0C34/Rs2dPeb3eMg9k33///Ro9erRmzZqlq666SnfccYc+/vhjtWrVqtxtX3jhhZo0aZLmzp2ra665RqtXr9Ztt92mmJiYKtV23O233y6Xy6X+/fsrNTVVBw8erNb7AaA+ifBzMygAAKc1YcIE7d69O/CAOAAgGFcsAAAox5w5c/TNN9/ou+++04IFC7R8+XINHDjQ6rIAwLa4YgEAsJ3jXzhXngsvvFAvv/xyrdfw29/+VuvXr1d+fr5at26tIUOG6Oabb671/QJAfUVjAQCwncOHDwfNTHWyBg0alJk2FgBgPRoLAAAAACHjGQsAAAAAIaOxAAAAABAyGgsAAAAAIaOxAAAAABAyGgsAAAAAIaOxAAAAABAyGgsAAAAAIaOxAAAAABCy/wdZEQok2bwbcQAAAABJRU5ErkJggg==",
      "text/plain": [
       "<Figure size 800x500 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure(figsize=(8, 5))\n",
    "df_total[\"audio_weight\"].hist(bins=np.linspace(0, 1, 100), color=\"skyblue\", edgecolor=\"black\")\n",
    "print_percentiles(df_total[\"audio_weight\"])\n",
    "plt.title(\"Distribution of audio_weight\")\n",
    "plt.xlabel(\"audio_weight\")\n",
    "plt.ylabel(\"Counts\")\n",
    "plt.grid(True, linestyle=\"--\", alpha=0.6)\n",
    "plt.tight_layout()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Fetch other parameters"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "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.15"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
