{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "ae9b8ff2-033e-4e48-926a-62c43535bba4",
   "metadata": {},
   "outputs": [],
   "source": [
    "import ethoscopy as etho\n",
    "import pandas as pd\n",
    "from scipy.stats import mannwhitneyu\n",
    "import matplotlib.pyplot as plt\n",
    "import numpy as np\n",
    "import seaborn as sns\n",
    "from scipy.stats import wilcoxon, shapiro, ttest_rel"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "6cbb4f52-dd5f-4888-9c9e-ba4f1f6dc429",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'2.1.0'"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "etho.__version__"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "dc5c910a-b8ac-4574-87f6-3df51839a50e",
   "metadata": {},
   "outputs": [],
   "source": [
    "meta = '/home/rdingjin/UASxGal4_2026-04-28/metadata_phase6_11H(1).csv' \n",
    "local = '/mnt/ethoscope_results'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "78e2a925-62ab-4c2c-bd11-e27e1b6789f5",
   "metadata": {},
   "outputs": [],
   "source": [
    "metadata = etho.link_meta_index(meta, local)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "65d71cd5-21c5-4cc0-a19b-7de730b45a65",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Loading ROI_1 from ETHOSCOPE_302\n",
      "Loading ROI_2 from ETHOSCOPE_302\n",
      "Loading ROI_3 from ETHOSCOPE_302\n",
      "Loading ROI_4 from ETHOSCOPE_302\n",
      "Loading ROI_5 from ETHOSCOPE_302\n",
      "Loading ROI_6 from ETHOSCOPE_302\n",
      "Loading ROI_7 from ETHOSCOPE_302\n",
      "Loading ROI_8 from ETHOSCOPE_302\n",
      "Loading ROI_9 from ETHOSCOPE_302\n",
      "Loading ROI_10 from ETHOSCOPE_302\n",
      "Loading ROI_11 from ETHOSCOPE_302\n",
      "Loading ROI_12 from ETHOSCOPE_302\n",
      "Loading ROI_13 from ETHOSCOPE_302\n",
      "Loading ROI_14 from ETHOSCOPE_302\n",
      "Loading ROI_15 from ETHOSCOPE_302\n",
      "Loading ROI_16 from ETHOSCOPE_302\n",
      "Loading ROI_17 from ETHOSCOPE_302\n",
      "Loading ROI_18 from ETHOSCOPE_302\n",
      "Loading ROI_19 from ETHOSCOPE_302\n",
      "Loading ROI_20 from ETHOSCOPE_302\n"
     ]
    }
   ],
   "source": [
    "data = etho.load_ethoscope(metadata, reference_hour = 9.0, FUN = etho.sleep_annotation)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "a2c12f1d-3ca9-469b-9447-7d117f320006",
   "metadata": {},
   "outputs": [],
   "source": [
    "df = etho.behavpy(data, metadata, check = True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "e256c265-07b7-4d90-96ed-44d2aa76f14d",
   "metadata": {},
   "outputs": [],
   "source": [
    "df.to_pickle('/home/rdingjin/UASxGal4_2026-04-28/phase6.pkl')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "1ee0efda-db87-4de1-8ee0-dea02fd3348f",
   "metadata": {},
   "outputs": [],
   "source": [
    "import ethoscopy as etho\n",
    "import pandas as pd\n",
    "from scipy.stats import mannwhitneyu\n",
    "import matplotlib.pyplot as plt\n",
    "import numpy as np\n",
    "import seaborn as sns\n",
    "from scipy.stats import wilcoxon, shapiro, ttest_rel\n",
    "df = pd.read_pickle('/home/rdingjin/UASxGal4_2026-04-28/phase6.pkl')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "b3073dcc-7801-45dc-a24a-3e2e91006bdf",
   "metadata": {},
   "outputs": [],
   "source": [
    "df = df.baseline(column = 'baseline')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "124a805c-1cf8-44d0-b114-71329cb0ede5",
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      " ==== METADATA ====\n",
      "\n",
      "                                     date   machine_name  region_id  \\\n",
      "id                                                                    \n",
      "2026-04-28_15-28-39_30232c|01  2026-04-28  ETHOSCOPE_302          1   \n",
      "2026-04-28_15-28-39_30232c|02  2026-04-28  ETHOSCOPE_302          2   \n",
      "2026-04-28_15-28-39_30232c|03  2026-04-28  ETHOSCOPE_302          3   \n",
      "2026-04-28_15-28-39_30232c|04  2026-04-28  ETHOSCOPE_302          4   \n",
      "2026-04-28_15-28-39_30232c|05  2026-04-28  ETHOSCOPE_302          5   \n",
      "2026-04-28_15-28-39_30232c|06  2026-04-28  ETHOSCOPE_302          6   \n",
      "2026-04-28_15-28-39_30232c|07  2026-04-28  ETHOSCOPE_302          7   \n",
      "2026-04-28_15-28-39_30232c|08  2026-04-28  ETHOSCOPE_302          8   \n",
      "2026-04-28_15-28-39_30232c|09  2026-04-28  ETHOSCOPE_302          9   \n",
      "2026-04-28_15-28-39_30232c|10  2026-04-28  ETHOSCOPE_302         10   \n",
      "2026-04-28_15-28-39_30232c|11  2026-04-28  ETHOSCOPE_302         11   \n",
      "2026-04-28_15-28-39_30232c|12  2026-04-28  ETHOSCOPE_302         12   \n",
      "2026-04-28_15-28-39_30232c|13  2026-04-28  ETHOSCOPE_302         13   \n",
      "2026-04-28_15-28-39_30232c|14  2026-04-28  ETHOSCOPE_302         14   \n",
      "2026-04-28_15-28-39_30232c|15  2026-04-28  ETHOSCOPE_302         15   \n",
      "2026-04-28_15-28-39_30232c|16  2026-04-28  ETHOSCOPE_302         16   \n",
      "2026-04-28_15-28-39_30232c|17  2026-04-28  ETHOSCOPE_302         17   \n",
      "2026-04-28_15-28-39_30232c|18  2026-04-28  ETHOSCOPE_302         18   \n",
      "2026-04-28_15-28-39_30232c|19  2026-04-28  ETHOSCOPE_302         19   \n",
      "2026-04-28_15-28-39_30232c|20  2026-04-28  ETHOSCOPE_302         20   \n",
      "\n",
      "                               sleep_deprived                         species  \\\n",
      "id                                                                              \n",
      "2026-04-28_15-28-39_30232c|01            True  UAS_ChRmine_attP5 x 11H05_Gal4   \n",
      "2026-04-28_15-28-39_30232c|02           False  UAS_ChRmine_attP5 x 11H05_Gal4   \n",
      "2026-04-28_15-28-39_30232c|03            True  UAS_ChRmine_attP5 x 11H05_Gal4   \n",
      "2026-04-28_15-28-39_30232c|04           False  UAS_ChRmine_attP5 x 11H05_Gal4   \n",
      "2026-04-28_15-28-39_30232c|05            True  UAS_ChRmine_attP5 x 11H05_Gal4   \n",
      "2026-04-28_15-28-39_30232c|06           False  UAS_ChRmine_attP5 x 11H05_Gal4   \n",
      "2026-04-28_15-28-39_30232c|07            True  UAS_ChRmine_attP5 x 11H05_Gal4   \n",
      "2026-04-28_15-28-39_30232c|08           False  UAS_ChRmine_attP5 x 11H05_Gal4   \n",
      "2026-04-28_15-28-39_30232c|09            True  UAS_ChRmine_attP5 x 11H05_Gal4   \n",
      "2026-04-28_15-28-39_30232c|10           False  UAS_ChRmine_attP5 x 11H05_Gal4   \n",
      "2026-04-28_15-28-39_30232c|11           False  UAS_ChRmine_attP5 x 11H05_Gal4   \n",
      "2026-04-28_15-28-39_30232c|12            True  UAS_ChRmine_attP5 x 11H05_Gal4   \n",
      "2026-04-28_15-28-39_30232c|13           False  UAS_ChRmine_attP5 x 11H05_Gal4   \n",
      "2026-04-28_15-28-39_30232c|14            True  UAS_ChRmine_attP5 x 11H05_Gal4   \n",
      "2026-04-28_15-28-39_30232c|15           False  UAS_ChRmine_attP5 x 11H05_Gal4   \n",
      "2026-04-28_15-28-39_30232c|16            True  UAS_ChRmine_attP5 x 11H05_Gal4   \n",
      "2026-04-28_15-28-39_30232c|17           False  UAS_ChRmine_attP5 x 11H05_Gal4   \n",
      "2026-04-28_15-28-39_30232c|18            True  UAS_ChRmine_attP5 x 11H05_Gal4   \n",
      "2026-04-28_15-28-39_30232c|19           False  UAS_ChRmine_attP5 x 11H05_Gal4   \n",
      "2026-04-28_15-28-39_30232c|20            True  UAS_ChRmine_attP5 x 11H05_Gal4   \n",
      "\n",
      "                                      food  baseline   sex      time  \n",
      "id                                                                    \n",
      "2026-04-28_15-28-39_30232c|01  normal_food         0  male  15-28-39  \n",
      "2026-04-28_15-28-39_30232c|02  normal_food         0  male  15-28-39  \n",
      "2026-04-28_15-28-39_30232c|03  normal_food         0  male  15-28-39  \n",
      "2026-04-28_15-28-39_30232c|04  normal_food         0  male  15-28-39  \n",
      "2026-04-28_15-28-39_30232c|05  normal_food         0  male  15-28-39  \n",
      "2026-04-28_15-28-39_30232c|06  normal_food         0  male  15-28-39  \n",
      "2026-04-28_15-28-39_30232c|07  normal_food         0  male  15-28-39  \n",
      "2026-04-28_15-28-39_30232c|08  normal_food         0  male  15-28-39  \n",
      "2026-04-28_15-28-39_30232c|09  normal_food         0  male  15-28-39  \n",
      "2026-04-28_15-28-39_30232c|10  normal_food         0  male  15-28-39  \n",
      "2026-04-28_15-28-39_30232c|11  normal_food         0  male  15-28-39  \n",
      "2026-04-28_15-28-39_30232c|12  normal_food         0  male  15-28-39  \n",
      "2026-04-28_15-28-39_30232c|13  normal_food         0  male  15-28-39  \n",
      "2026-04-28_15-28-39_30232c|14  normal_food         0  male  15-28-39  \n",
      "2026-04-28_15-28-39_30232c|15  normal_food         0  male  15-28-39  \n",
      "2026-04-28_15-28-39_30232c|16  normal_food         0  male  15-28-39  \n",
      "2026-04-28_15-28-39_30232c|17  normal_food         0  male  15-28-39  \n",
      "2026-04-28_15-28-39_30232c|18  normal_food         0  male  15-28-39  \n",
      "2026-04-28_15-28-39_30232c|19  normal_food         0  male  15-28-39  \n",
      "2026-04-28_15-28-39_30232c|20  normal_food         0  male  15-28-39  \n",
      " ====== DATA ======\n",
      "\n",
      "                                    t           x          y          w  \\\n",
      "id                                                                        \n",
      "2026-04-28_15-28-39_30232c|01   23320  193.227273  28.863636  33.681818   \n",
      "2026-04-28_15-28-39_30232c|01   23330  286.868421  30.078947  33.000000   \n",
      "2026-04-28_15-28-39_30232c|01   23340  310.000000  31.000000  33.000000   \n",
      "2026-04-28_15-28-39_30232c|01   23350  310.000000  31.000000  33.000000   \n",
      "2026-04-28_15-28-39_30232c|01   23360  310.000000  31.000000  33.000000   \n",
      "...                               ...         ...        ...        ...   \n",
      "2026-04-28_15-28-39_30232c|20  618010  313.533333  19.000000  28.866667   \n",
      "2026-04-28_15-28-39_30232c|20  618020  313.392857  19.000000  28.964286   \n",
      "2026-04-28_15-28-39_30232c|20  618030  313.192308  19.000000  29.076923   \n",
      "2026-04-28_15-28-39_30232c|20  618040  313.161290  19.000000  29.032258   \n",
      "2026-04-28_15-28-39_30232c|20  618050  313.375000  19.000000  29.000000   \n",
      "\n",
      "                                       h        phi  max_velocity  \\\n",
      "id                                                                  \n",
      "2026-04-28_15-28-39_30232c|01  14.000000  41.181818     89.511482   \n",
      "2026-04-28_15-28-39_30232c|01  13.447368  32.289474     20.600547   \n",
      "2026-04-28_15-28-39_30232c|01  13.000000   0.000000      1.428495   \n",
      "2026-04-28_15-28-39_30232c|01  13.000000   0.000000      1.428495   \n",
      "2026-04-28_15-28-39_30232c|01  13.000000   0.000000      1.428495   \n",
      "...                                  ...        ...           ...   \n",
      "2026-04-28_15-28-39_30232c|20  11.100000  13.600000      0.774246   \n",
      "2026-04-28_15-28-39_30232c|20  11.035714  15.892857      0.744524   \n",
      "2026-04-28_15-28-39_30232c|20  11.000000  15.846154      0.737698   \n",
      "2026-04-28_15-28-39_30232c|20  11.000000  15.935484      0.797772   \n",
      "2026-04-28_15-28-39_30232c|20  11.031250  16.312500      0.803302   \n",
      "\n",
      "                               mean_velocity      dist  has_interacted  \\\n",
      "id                                                                       \n",
      "2026-04-28_15-28-39_30232c|01       9.254820  0.610818             0.0   \n",
      "2026-04-28_15-28-39_30232c|01       3.274451  0.373287             0.0   \n",
      "2026-04-28_15-28-39_30232c|01       1.428495  0.158563             0.0   \n",
      "2026-04-28_15-28-39_30232c|01       1.428495  0.175705             0.0   \n",
      "2026-04-28_15-28-39_30232c|01       1.428495  0.124279             0.0   \n",
      "...                                      ...       ...             ...   \n",
      "2026-04-28_15-28-39_30232c|20       0.663063  0.059676             0.0   \n",
      "2026-04-28_15-28-39_30232c|20       0.667116  0.056038             0.0   \n",
      "2026-04-28_15-28-39_30232c|20       0.657137  0.051257             0.0   \n",
      "2026-04-28_15-28-39_30232c|20       0.670289  0.062337             0.0   \n",
      "2026-04-28_15-28-39_30232c|20       0.680839  0.065361             0.0   \n",
      "\n",
      "                               beam_cross moving  micro   walk  \\\n",
      "id                                                               \n",
      "2026-04-28_15-28-39_30232c|01         0.0   True  False   True   \n",
      "2026-04-28_15-28-39_30232c|01         0.0   True  False   True   \n",
      "2026-04-28_15-28-39_30232c|01         0.0   True   True  False   \n",
      "2026-04-28_15-28-39_30232c|01         0.0   True   True  False   \n",
      "2026-04-28_15-28-39_30232c|01         0.0   True   True  False   \n",
      "...                                   ...    ...    ...    ...   \n",
      "2026-04-28_15-28-39_30232c|20         0.0  False  False  False   \n",
      "2026-04-28_15-28-39_30232c|20         0.0  False  False  False   \n",
      "2026-04-28_15-28-39_30232c|20         0.0  False  False  False   \n",
      "2026-04-28_15-28-39_30232c|20         0.0  False  False  False   \n",
      "2026-04-28_15-28-39_30232c|20         0.0  False  False  False   \n",
      "\n",
      "                               is_interpolated  asleep  \n",
      "id                                                      \n",
      "2026-04-28_15-28-39_30232c|01            False   False  \n",
      "2026-04-28_15-28-39_30232c|01            False   False  \n",
      "2026-04-28_15-28-39_30232c|01            False   False  \n",
      "2026-04-28_15-28-39_30232c|01            False   False  \n",
      "2026-04-28_15-28-39_30232c|01            False   False  \n",
      "...                                        ...     ...  \n",
      "2026-04-28_15-28-39_30232c|20            False   False  \n",
      "2026-04-28_15-28-39_30232c|20            False   False  \n",
      "2026-04-28_15-28-39_30232c|20            False   False  \n",
      "2026-04-28_15-28-39_30232c|20            False   False  \n",
      "2026-04-28_15-28-39_30232c|20            False   False  \n",
      "\n",
      "[1188874 rows x 16 columns]\n"
     ]
    }
   ],
   "source": [
    "df.display()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "id": "de0b9beb-7861-4091-b443-1913e4aa04b8",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/srv/venv/lib/python3.12/site-packages/ethoscopy/behavpy_core.py:1611: FutureWarning: DataFrameGroupBy.apply operated on the grouping columns. This behavior is deprecated, and in a future version of pandas the grouping columns will be excluded from the operation. Either pass `include_groups=False` to exclude the groupings or explicitly select the grouping columns after groupby to silence this warning.\n",
      "  tdf.groupby(\"id\", group_keys=False).apply(\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 81596 characters]",
      "text/plain": [
       "<Figure size 950x200 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "start_hour = 0\n",
    "end_hour = 120\n",
    "fig = df.t_filter(start_time=start_hour, end_time=end_hour).heatmap(variable = 'asleep')\n",
    "fig.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "id": "57702793-afd1-4824-b360-50f41cd2161e",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Task was destroyed but it is pending!\n",
      "task: <Task pending name='Task-529' coro=<_async_in_context.<locals>.run_in_context() done, defined at /srv/venv/lib/python3.12/site-packages/ipykernel/utils.py:57> wait_for=<Task pending name='Task-530' coro=<Kernel.shell_main() running at /srv/venv/lib/python3.12/site-packages/ipykernel/kernelbase.py:597> cb=[Task.task_wakeup()]> cb=[ZMQStream._run_callback.<locals>._log_error() at /srv/venv/lib/python3.12/site-packages/zmq/eventloop/zmqstream.py:563]>\n",
      "/srv/venv/lib/python3.12/site-packages/matplotlib/cbook.py:260: RuntimeWarning: coroutine 'Kernel.shell_main' was never awaited\n",
      "  self._signals = None if signals is None else list(signals)  # Copy it.\n",
      "Task was destroyed but it is pending!\n",
      "task: <Task pending name='Task-530' coro=<Kernel.shell_main() running at /srv/venv/lib/python3.12/site-packages/ipykernel/kernelbase.py:597> cb=[Task.task_wakeup()]>\n",
      "Task was destroyed but it is pending!\n",
      "task: <Task pending name='Task-547' coro=<_async_in_context.<locals>.run_in_context() done, defined at /srv/venv/lib/python3.12/site-packages/ipykernel/utils.py:57> wait_for=<Task pending name='Task-548' coro=<Kernel.shell_main() running at /srv/venv/lib/python3.12/site-packages/ipykernel/kernelbase.py:597> cb=[Task.task_wakeup()]> cb=[ZMQStream._run_callback.<locals>._log_error() at /srv/venv/lib/python3.12/site-packages/zmq/eventloop/zmqstream.py:563]>\n",
      "Task was destroyed but it is pending!\n",
      "task: <Task pending name='Task-548' coro=<Kernel.shell_main() running at /srv/venv/lib/python3.12/site-packages/ipykernel/kernelbase.py:597> cb=[Task.task_wakeup()]>\n",
      "Task was destroyed but it is pending!\n",
      "task: <Task pending name='Task-565' coro=<_async_in_context.<locals>.run_in_context() done, defined at /srv/venv/lib/python3.12/site-packages/ipykernel/utils.py:57> wait_for=<Task pending name='Task-566' coro=<Kernel.shell_main() running at /srv/venv/lib/python3.12/site-packages/ipykernel/kernelbase.py:597> cb=[Task.task_wakeup()]> cb=[ZMQStream._run_callback.<locals>._log_error() at /srv/venv/lib/python3.12/site-packages/zmq/eventloop/zmqstream.py:563]>\n",
      "Task was destroyed but it is pending!\n",
      "task: <Task pending name='Task-566' coro=<Kernel.shell_main() running at /srv/venv/lib/python3.12/site-packages/ipykernel/kernelbase.py:597> cb=[Task.task_wakeup()]>\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 227064 characters]",
      "text/plain": [
       "<Figure size 1266.67x483.333 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "start_hour = 0\n",
    "end_hour = 120\n",
    "\n",
    "# Generate plot from Ethoscopy\n",
    "fig = df.t_filter(start_time=start_hour, end_time=end_hour).plot_overtime(variable='asleep', avg_window=30, grids=True)\n",
    "\n",
    "# Extract the main axis from the figure\n",
    "ax = fig.axes[0]\n",
    "\n",
    "# Add shading stimulus shading\n",
    "# Draw a vertical span from ZT 48 to ZT 72\n",
    "ax.axvspan(72, 96, color='#ff4c4c', alpha=0.3, zorder=1)\n",
    "\n",
    "# Set custom labels\n",
    "ax.set_xlabel(\"Zeitgeber Time (Hours)\", fontsize=12)\n",
    "ax.set_ylabel(\"Fraction of Time Asleep\", fontsize=12)\n",
    "\n",
    "# Show plot\n",
    "fig.show()\n",
    "\n",
    "# Save as a high-resolution PNG\n",
    "plt.savefig(\"Figure_6(11H)_1.png\", dpi=600, bbox_inches='tight')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "id": "f64dea93-8b25-462e-9e75-e47a3703f5e9",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "--- Individual Fly Sleep (Baseline: 0h to 72h, Averaged per day) ---\n",
      "             Fly_Label  Base_Sleep_24h  Base_Day_12h  Base_Night_12h\n",
      "ETHOSCOPE_302 - Fly 01        6.119444      2.753858        3.861111\n",
      "ETHOSCOPE_302 - Fly 02        8.446296      3.862627        5.278704\n",
      "ETHOSCOPE_302 - Fly 03       10.862963      4.041404        7.549074\n",
      "ETHOSCOPE_302 - Fly 04        5.987037      2.223184        4.163889\n",
      "ETHOSCOPE_302 - Fly 05        8.436111      3.732781        5.375000\n",
      "ETHOSCOPE_302 - Fly 06        8.968519      3.315017        6.250000\n",
      "ETHOSCOPE_302 - Fly 07       10.404630      3.748589        7.330556\n",
      "ETHOSCOPE_302 - Fly 08        5.198148      2.900640        2.819444\n",
      "ETHOSCOPE_302 - Fly 09        4.959259      3.109815        2.409259\n",
      "ETHOSCOPE_302 - Fly 10        8.729630      5.744825        4.018519\n",
      "ETHOSCOPE_302 - Fly 11        6.402778      2.366802        4.462037\n",
      "ETHOSCOPE_302 - Fly 12       11.563889      4.842680        7.592593\n",
      "ETHOSCOPE_302 - Fly 13        7.686111      4.075663        4.344444\n",
      "ETHOSCOPE_302 - Fly 14        9.391667      4.764540        5.485185\n",
      "ETHOSCOPE_302 - Fly 15        8.819444      3.817463        5.688889\n",
      "ETHOSCOPE_302 - Fly 16        7.112037      1.676703        5.737037\n",
      "ETHOSCOPE_302 - Fly 17        8.734259      2.290930        6.855556\n",
      "ETHOSCOPE_302 - Fly 18        5.836111      2.669678        3.647222\n",
      "ETHOSCOPE_302 - Fly 19        8.003704      3.871259        4.829630\n",
      "ETHOSCOPE_302 - Fly 20       11.876852      5.086871        7.706481\n",
      "... (Showing first 20 rows)\n",
      "\n",
      "--- Grand Summary Statistics (Baseline: 0h to 72h) ---\n",
      "Total Flies Analyzed: n = 20\n",
      "\n",
      "[ OVERALL SLEEP (Scaled to 24h Baseline Average) ]\n",
      "Mean ± SEM:   8.18 ± 0.46 hours\n",
      "Median:       8.44 hours\n",
      "\n",
      "[ DAY TIME (ZT 0-12, Averaged to 12h blocks) ]\n",
      "Mean ± SEM:   3.54 ± 0.24 hours\n",
      "Median:       3.74 hours\n",
      "\n",
      "[ NIGHT TIME (ZT 12-24, Averaged to 12h blocks) ]\n",
      "Mean ± SEM:   5.27 ± 0.36 hours\n",
      "Median:       5.33 hours\n"
     ]
    }
   ],
   "source": [
    "# BASELINE\n",
    "\n",
    "# Define baseline time period\n",
    "start_hour = 0\n",
    "end_hour = 72\n",
    "\n",
    "# Filter the dataset to ONLY include data within specific baseline window\n",
    "base_df = df.t_filter(start_time=start_hour, end_time=end_hour).copy()\n",
    "\n",
    "# Calculate Overall 24h Baseline Average\n",
    "sleep_hours = (base_df.groupby('id')['asleep'].sum() * 10) / 3600\n",
    "\n",
    "# (72 - 0) / 24 evaluates to exactly 3 days. \n",
    "# Dividing total sleep by 3 to average the 72 hours into a single 24-hour metric\n",
    "days_tracked = (end_hour - start_hour) / 24 \n",
    "base_overall = (sleep_hours / days_tracked).reset_index(name='Base_Sleep_24h')\n",
    "\n",
    "# Calculate Day/Night 12h Baseline Averages\n",
    "base_df['zt_hour'] = (base_df['t'] / 3600) % 24\n",
    "base_df['Phase'] = np.where(base_df['zt_hour'] < 12, 'Day', 'Night')\n",
    "\n",
    "base_phase = base_df.groupby(['id', 'Phase']).agg(\n",
    "    total_sleep_epochs=('asleep', 'sum'),\n",
    "    total_tracking_epochs=('t', 'count')\n",
    ").reset_index()\n",
    "\n",
    "# Tracking_Hours will be ~24 for Day and ~24 for Night \n",
    "# Dividing sleep by tracking hours and multiplying by 12 averages it to a single 12h block.\n",
    "base_phase['Sleep_Hours'] = (base_phase['total_sleep_epochs'] * 10) / 3600\n",
    "base_phase['Tracking_Hours'] = (base_phase['total_tracking_epochs'] * 10) / 3600\n",
    "base_phase['Base_Sleep_12h'] = (base_phase['Sleep_Hours'] / base_phase['Tracking_Hours']) * 12\n",
    "\n",
    "base_pivot = base_phase.pivot(index='id', columns='Phase', values='Base_Sleep_12h').reset_index()\n",
    "# Rename columns\n",
    "base_pivot.columns = ['id', 'Base_Day_12h', 'Base_Night_12h']\n",
    "\n",
    "# Merge and clean up data\n",
    "merged_df = pd.merge(base_overall, base_pivot, on='id')\n",
    "\n",
    "merged_df['Machine'] = merged_df['id'].map(df.meta['machine_name'])\n",
    "merged_df['Tube'] = merged_df['id'].apply(lambda x: str(x).split('|')[-1])\n",
    "merged_df['Fly_Label'] = merged_df['Machine'] + \" - Fly \" + merged_df['Tube']\n",
    "\n",
    "clean_table = merged_df.dropna(subset=['Machine']).sort_values(by=['Machine', 'Tube'])\n",
    "baseline_stats = clean_table[['Fly_Label', 'Base_Sleep_24h', 'Base_Day_12h', 'Base_Night_12h']]\n",
    "\n",
    "# PRINT RESULTS\n",
    "print(f\"--- Individual Fly Sleep (Baseline: {start_hour}h to {end_hour}h, Averaged per day) ---\")\n",
    "print(baseline_stats.head(20).to_string(index=False)) \n",
    "print(\"... (Showing first 20 rows)\\n\")\n",
    "\n",
    "print(f\"--- Grand Summary Statistics (Baseline: {start_hour}h to {end_hour}h) ---\")\n",
    "print(f\"Total Flies Analyzed: n = {len(baseline_stats)}\")\n",
    "\n",
    "# 1. OVERALL 24H STATS\n",
    "print(\"\\n[ OVERALL SLEEP (Scaled to 24h Baseline Average) ]\")\n",
    "print(f\"Mean ± SEM:   {baseline_stats['Base_Sleep_24h'].mean():.2f} ± {baseline_stats['Base_Sleep_24h'].sem():.2f} hours\")\n",
    "print(f\"Median:       {baseline_stats['Base_Sleep_24h'].median():.2f} hours\")\n",
    "\n",
    "# 2. DAY TIME STATS\n",
    "print(f\"\\n[ DAY TIME (ZT 0-12, Averaged to 12h blocks) ]\")\n",
    "print(f\"Mean ± SEM:   {baseline_stats['Base_Day_12h'].mean():.2f} ± {baseline_stats['Base_Day_12h'].sem():.2f} hours\")\n",
    "print(f\"Median:       {baseline_stats['Base_Day_12h'].median():.2f} hours\")\n",
    "\n",
    "# 3. NIGHT TIME STATS\n",
    "print(f\"\\n[ NIGHT TIME (ZT 12-24, Averaged to 12h blocks) ]\")\n",
    "print(f\"Mean ± SEM:   {baseline_stats['Base_Night_12h'].mean():.2f} ± {baseline_stats['Base_Night_12h'].sem():.2f} hours\")\n",
    "print(f\"Median:       {baseline_stats['Base_Night_12h'].median():.2f} hours\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "id": "a89a9da0-2db2-4006-a9f0-0addb71ecac5",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "--- Individual Fly Sleep (Stimulus: 72h to 96h) ---\n",
      "             Fly_Label  Stim_Sleep_24h  Stim_Day_12h  Stim_Night_12h\n",
      "ETHOSCOPE_302 - Fly 01        8.388889      1.888889        6.500000\n",
      "ETHOSCOPE_302 - Fly 02        9.630556      4.277778        5.352778\n",
      "ETHOSCOPE_302 - Fly 03       12.416667      2.661111        9.755556\n",
      "ETHOSCOPE_302 - Fly 04        6.447222      1.694444        4.752778\n",
      "ETHOSCOPE_302 - Fly 05        9.386111      3.919444        5.466667\n",
      "ETHOSCOPE_302 - Fly 06       10.580556      2.830556        7.750000\n",
      "ETHOSCOPE_302 - Fly 07       10.122222      3.200000        6.922222\n",
      "ETHOSCOPE_302 - Fly 08        5.427778      2.750000        2.677778\n",
      "ETHOSCOPE_302 - Fly 09        5.622222      2.291667        3.330556\n",
      "ETHOSCOPE_302 - Fly 10       10.438889      4.280556        6.158333\n",
      "ETHOSCOPE_302 - Fly 11        6.063889      1.286111        4.777778\n",
      "ETHOSCOPE_302 - Fly 12       14.011111      5.405556        8.605556\n",
      "ETHOSCOPE_302 - Fly 13        8.586111      2.572222        6.013889\n",
      "ETHOSCOPE_302 - Fly 14       11.230556      4.672222        6.558333\n",
      "ETHOSCOPE_302 - Fly 15       11.713889      4.969444        6.744444\n",
      "ETHOSCOPE_302 - Fly 16        6.391667      1.363889        5.027778\n",
      "ETHOSCOPE_302 - Fly 17        7.536111      1.986111        5.550000\n",
      "ETHOSCOPE_302 - Fly 18        4.133333      1.169444        2.963889\n",
      "ETHOSCOPE_302 - Fly 19       14.430556      5.975000        8.455556\n",
      "ETHOSCOPE_302 - Fly 20       12.691667      4.383333        8.308333\n",
      "... (Showing first 20 rows)\n",
      "\n",
      "--- Grand Summary Statistics (Stimulus: 72h to 96h) ---\n",
      "Total Flies Analyzed: n = 20\n",
      "\n",
      "[ OVERALL SLEEP (24h Stimulus Block) ]\n",
      "Mean ± SEM:   9.26 ± 0.67 hours\n",
      "Median:       9.51 hours\n",
      "\n",
      "[ DAY TIME (ZT 0-12 during Stimulus) ]\n",
      "Mean ± SEM:   3.18 ± 0.33 hours\n",
      "Median:       2.79 hours\n",
      "\n",
      "[ NIGHT TIME (ZT 12-24 during Stimulus) ]\n",
      "Mean ± SEM:   6.08 ± 0.43 hours\n",
      "Median:       6.09 hours\n"
     ]
    }
   ],
   "source": [
    "# Define stimulus time period\n",
    "start_hour = 72\n",
    "end_hour = 96\n",
    "\n",
    "# Filter the dataset to ONLY include data within specific stimulus window\n",
    "stim_df = df.t_filter(start_time=start_hour, end_time=end_hour).copy()\n",
    "\n",
    "# Calculate Overall 24h Stimulus Average\n",
    "sleep_hours = (stim_df.groupby('id')['asleep'].sum() * 10) / 3600\n",
    "days_tracked = (end_hour - start_hour) / 24 \n",
    "stim_overall = (sleep_hours / days_tracked).reset_index(name='Stim_Sleep_24h')\n",
    "\n",
    "# Calculate Day/Night 12h Stimulus Averages\n",
    "stim_df['zt_hour'] = (stim_df['t'] / 3600) % 24\n",
    "stim_df['Phase'] = np.where(stim_df['zt_hour'] < 12, 'Day', 'Night')\n",
    "\n",
    "stim_phase = stim_df.groupby(['id', 'Phase']).agg(\n",
    "    total_sleep_epochs=('asleep', 'sum'),\n",
    "    total_tracking_epochs=('t', 'count')\n",
    ").reset_index()\n",
    "\n",
    "# Tracking_Hours will now be ~12 for Day and ~12 for Night\n",
    "# Dividing sleep by tracking hours and multiplying by 12 averages it to a single 12h block.\n",
    "stim_phase['Sleep_Hours'] = (stim_phase['total_sleep_epochs'] * 10) / 3600\n",
    "stim_phase['Tracking_Hours'] = (stim_phase['total_tracking_epochs'] * 10) / 3600\n",
    "stim_phase['Stim_Sleep_12h'] = (stim_phase['Sleep_Hours'] / stim_phase['Tracking_Hours']) * 12\n",
    "\n",
    "stim_pivot = stim_phase.pivot(index='id', columns='Phase', values='Stim_Sleep_12h').reset_index()\n",
    "# Rename columns \n",
    "stim_pivot.columns = ['id', 'Stim_Day_12h', 'Stim_Night_12h']\n",
    "\n",
    "# Merge and clean up data\n",
    "merged_df = pd.merge(stim_overall, stim_pivot, on='id')\n",
    "\n",
    "merged_df['Machine'] = merged_df['id'].map(df.meta['machine_name'])\n",
    "merged_df['Tube'] = merged_df['id'].apply(lambda x: str(x).split('|')[-1])\n",
    "merged_df['Fly_Label'] = merged_df['Machine'] + \" - Fly \" + merged_df['Tube']\n",
    "\n",
    "clean_table = merged_df.dropna(subset=['Machine']).sort_values(by=['Machine', 'Tube'])\n",
    "stim_stats = clean_table[['Fly_Label', 'Stim_Sleep_24h', 'Stim_Day_12h', 'Stim_Night_12h']]\n",
    "\n",
    "# PRINT RESULTS\n",
    "print(f\"--- Individual Fly Sleep (Stimulus: {start_hour}h to {end_hour}h) ---\")\n",
    "print(stim_stats.head(20).to_string(index=False)) \n",
    "print(\"... (Showing first 20 rows)\\n\")\n",
    "\n",
    "print(f\"--- Grand Summary Statistics (Stimulus: {start_hour}h to {end_hour}h) ---\")\n",
    "print(f\"Total Flies Analyzed: n = {len(stim_stats)}\")\n",
    "\n",
    "# 1. OVERALL 24H STATS\n",
    "print(\"\\n[ OVERALL SLEEP (24h Stimulus Block) ]\")\n",
    "print(f\"Mean ± SEM:   {stim_stats['Stim_Sleep_24h'].mean():.2f} ± {stim_stats['Stim_Sleep_24h'].sem():.2f} hours\")\n",
    "print(f\"Median:       {stim_stats['Stim_Sleep_24h'].median():.2f} hours\")\n",
    "\n",
    "# 2. DAY TIME STATS\n",
    "print(f\"\\n[ DAY TIME (ZT 0-12 during Stimulus) ]\")\n",
    "print(f\"Mean ± SEM:   {stim_stats['Stim_Day_12h'].mean():.2f} ± {stim_stats['Stim_Day_12h'].sem():.2f} hours\")\n",
    "print(f\"Median:       {stim_stats['Stim_Day_12h'].median():.2f} hours\")\n",
    "\n",
    "# 3. NIGHT TIME STATS\n",
    "print(f\"\\n[ NIGHT TIME (ZT 12-24 during Stimulus) ]\")\n",
    "print(f\"Mean ± SEM:   {stim_stats['Stim_Night_12h'].mean():.2f} ± {stim_stats['Stim_Night_12h'].sem():.2f} hours\")\n",
    "print(f\"Median:       {stim_stats['Stim_Night_12h'].median():.2f} hours\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "id": "9be717e4-a077-468d-aafc-21479f1beac1",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "--- 24h Total Statistical Analysis ---\n",
      "Shapiro-Wilk P-value (Normality of differences): 0.0631\n",
      "Result: Data is normal. Used Paired T-test.\n",
      "P-value: 1.2030e-02\n",
      "Significance: *\n",
      "\n",
      "--- Daytime Statistical Analysis ---\n",
      "Shapiro-Wilk P-value (Normality of differences): 0.1149\n",
      "Result: Data is normal. Used Paired T-test.\n",
      "P-value: 9.3149e-02\n",
      "Significance: ns\n",
      "\n",
      "--- Nighttime Statistical Analysis ---\n",
      "Shapiro-Wilk P-value (Normality of differences): 0.9500\n",
      "Result: Data is normal. Used Paired T-test.\n",
      "P-value: 8.5019e-03\n",
      "Significance: **\n"
     ]
    }
   ],
   "source": [
    "# STATISTICS\n",
    "\n",
    "# Merge Baseline and Stimulus data on Fly_Label\n",
    "# This ensures we are comparing the SAME fly to itself\n",
    "paired_df = pd.merge(baseline_stats, stim_stats, on='Fly_Label')\n",
    "\n",
    "def run_paired_stats(df, base_col, stim_col, label):\n",
    "    # Calculate the differences for the paired test\n",
    "    diffs = df[stim_col] - df[base_col]\n",
    "    \n",
    "    # 2. Shapiro-Wilk Test for Normality\n",
    "    _, p_shapiro = shapiro(diffs)\n",
    "    \n",
    "    print(f\"\\n--- {label} Statistical Analysis ---\")\n",
    "    print(f\"Shapiro-Wilk P-value (Normality of differences): {p_shapiro:.4f}\")\n",
    "    \n",
    "    # 3. Determine Test: If P > 0.05, data is normal (use t-test). If P < 0.05, use Wilcoxon.\n",
    "    if p_shapiro > 0.05:\n",
    "        stat, p_val = ttest_rel(df[base_col], df[stim_col])\n",
    "        print(f\"Result: Data is normal. Used Paired T-test.\")\n",
    "    else:\n",
    "        stat, p_val = wilcoxon(df[base_col], df[stim_col])\n",
    "        print(f\"Result: Data is not normal. Used Wilcoxon Signed-Rank test.\")\n",
    "        \n",
    "    print(f\"P-value: {p_val:.4e}\")\n",
    "    if p_val < 0.0001: print(\"Significance: ****\")\n",
    "    elif p_val < 0.001: print(\"Significance: ***\")\n",
    "    elif p_val < 0.01: print(\"Significance: **\")\n",
    "    elif p_val < 0.05: print(\"Significance: *\")\n",
    "    else: print(\"Significance: ns\")\n",
    "\n",
    "# Run for all three metrics\n",
    "run_paired_stats(paired_df, 'Base_Sleep_24h', 'Stim_Sleep_24h', '24h Total')\n",
    "run_paired_stats(paired_df, 'Base_Day_12h', 'Stim_Day_12h', 'Daytime')\n",
    "run_paired_stats(paired_df, 'Base_Night_12h', 'Stim_Night_12h', 'Nighttime')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "id": "eeabf9c2-6a02-41ee-b756-a473a4224032",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 54988 characters]",
      "text/plain": [
       "<Figure size 700x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "#PLOT\n",
    "\n",
    "# 1. PREPARE DATA & CALCULATE STATS\n",
    "combined = pd.merge(baseline_stats, stim_stats, on='Fly_Label')\n",
    "\n",
    "# Calculate the paired statistics for the brackets\n",
    "p_values = {}\n",
    "metrics = {\n",
    "    '24h': ('Base_Sleep_24h', 'Stim_Sleep_24h'),\n",
    "    'Day': ('Base_Day_12h', 'Stim_Day_12h'),\n",
    "    'Night': ('Base_Night_12h', 'Stim_Night_12h')\n",
    "}\n",
    "\n",
    "for phase, (base_col, stim_col) in metrics.items():\n",
    "    diffs = combined[stim_col] - combined[base_col]\n",
    "    _, p_shapiro = shapiro(diffs)\n",
    "    \n",
    "    if p_shapiro > 0.05:\n",
    "        _, p_val = ttest_rel(combined[base_col], combined[stim_col])\n",
    "    else:\n",
    "        _, p_val = wilcoxon(combined[base_col], combined[stim_col])\n",
    "    p_values[phase] = p_val\n",
    "\n",
    "plot_df = combined.melt(id_vars=['Fly_Label'], var_name='Variable', value_name='Hours')\n",
    "plot_df['Condition'] = plot_df['Variable'].apply(lambda x: '24h' if '24h' in x else ('Day' if 'Day' in x else 'Night'))\n",
    "plot_df['State'] = plot_df['Variable'].apply(lambda x: 'Baseline' if 'Base' in x else 'Stimulus')\n",
    "\n",
    "# 2. GENERATE PLOT\n",
    "plt.figure(figsize=(7, 6))\n",
    "sns.set_theme(style=\"ticks\")\n",
    "\n",
    "order = ['24h', 'Day', 'Night']\n",
    "hue_order = ['Baseline', 'Stimulus']\n",
    "palette = {'Baseline': '#cccccc', 'Stimulus': '#ff4c4c'}\n",
    "\n",
    "# Boxplot \n",
    "sns.boxplot(\n",
    "    data=plot_df, x='Condition', y='Hours', hue='State', \n",
    "    order=order, hue_order=hue_order, palette=palette,\n",
    "    width=0.6, gap=0.2, boxprops={'edgecolor': 'black', 'alpha': 0.7},\n",
    "    medianprops={'color': 'black', 'linewidth': 1.5}, showfliers=False\n",
    ")\n",
    "\n",
    "# Stripplot\n",
    "sns.stripplot(\n",
    "    data=plot_df, x='Condition', y='Hours', hue='State', \n",
    "    order=order, hue_order=hue_order, dodge=True,\n",
    "    palette=['black', 'black'], alpha=0.5, size=4, jitter=0.05,\n",
    "    legend=False\n",
    ")\n",
    "\n",
    "# 3. ADD MEDIAN LABELS\n",
    "ax = plt.gca()\n",
    "medians = plot_df.groupby(['Condition', 'State'], sort=False)['Hours'].median()\n",
    "\n",
    "# Offsets remain exactly as provided\n",
    "offsets = {'Baseline': -0.4, 'Stimulus': 0.4}\n",
    "\n",
    "for i, cond in enumerate(order):\n",
    "    for state in hue_order:\n",
    "        val = medians[(cond, state)]\n",
    "        ax.text(i + offsets[state], val, f\"{val:.1f}h\", \n",
    "                ha='center', va='bottom', fontsize=10)\n",
    "\n",
    "# 4. ADD SIGNIFICANCE BRACKETS\n",
    "y_max = plot_df['Hours'].max()\n",
    "y_line = y_max + 1.0  \n",
    "h = 0.4               \n",
    "\n",
    "for i, cond in enumerate(order):\n",
    "    p = p_values[cond]\n",
    "    \n",
    "    if p < 0.0001: star = '****'\n",
    "    elif p < 0.001: star = '***'\n",
    "    elif p < 0.01: star = '**'\n",
    "    elif p < 0.05: star = '*'\n",
    "    else: star = 'ns'\n",
    "    \n",
    "    x1, x2 = i - 0.2, i + 0.2\n",
    "    plt.plot([x1, x1, x2, x2], [y_line, y_line+h, y_line+h, y_line], lw=1.5, c='k')\n",
    "    plt.text((x1+x2)*.5, y_line+h, star, ha='center', va='bottom', fontsize=12)\n",
    "\n",
    "# 5. FORMATTING\n",
    "sns.despine()\n",
    "plt.ylabel('Average time spent asleep (hours)', fontsize=12)\n",
    "plt.xlabel('')\n",
    "plt.xlim(-0.6, 2.5) \n",
    "\n",
    "plt.ylim(0, max(20, y_line + h + 1.5)) \n",
    "\n",
    "# Legend moved outside the plot to the right\n",
    "plt.legend(title='', frameon=False, loc='center left', bbox_to_anchor=(1, 0.5))\n",
    "plt.tight_layout()\n",
    "\n",
    "plt.savefig(\"Phase6(11H)_Baseline_vs_Stimulus.png\", dpi=600, bbox_inches='tight')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "id": "681dc07b-e5f7-4682-aee0-c8fca43af2ec",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "--- Delta Sleep (Stimulus - Baseline) per Fly ---\n",
      "             Fly_Label  Delta_24h  Delta_Day  Delta_Night\n",
      "ETHOSCOPE_302 - Fly 01   2.269444  -0.864969     2.638889\n",
      "ETHOSCOPE_302 - Fly 02   1.184259   0.415151     0.074074\n",
      "ETHOSCOPE_302 - Fly 03   1.553704  -1.380293     2.206481\n",
      "ETHOSCOPE_302 - Fly 04   0.460185  -0.528740     0.588889\n",
      "ETHOSCOPE_302 - Fly 05   0.950000   0.186663     0.091667\n",
      "ETHOSCOPE_302 - Fly 06   1.612037  -0.484461     1.500000\n",
      "ETHOSCOPE_302 - Fly 07  -0.282407  -0.548589    -0.408333\n",
      "ETHOSCOPE_302 - Fly 08   0.229630  -0.150640    -0.141667\n",
      "ETHOSCOPE_302 - Fly 09   0.662963  -0.818148     0.921296\n",
      "ETHOSCOPE_302 - Fly 10   1.709259  -1.464269     2.139815\n",
      "ETHOSCOPE_302 - Fly 11  -0.338889  -1.080690     0.315741\n",
      "ETHOSCOPE_302 - Fly 12   2.447222   0.562876     1.012963\n",
      "ETHOSCOPE_302 - Fly 13   0.900000  -1.503441     1.669444\n",
      "ETHOSCOPE_302 - Fly 14   1.838889  -0.092318     1.073148\n",
      "ETHOSCOPE_302 - Fly 15   2.894444   1.151981     1.055556\n",
      "ETHOSCOPE_302 - Fly 16  -0.720370  -0.312814    -0.709259\n",
      "ETHOSCOPE_302 - Fly 17  -1.198148  -0.304819    -1.305556\n",
      "ETHOSCOPE_302 - Fly 18  -1.702778  -1.500234    -0.683333\n",
      "ETHOSCOPE_302 - Fly 19   6.426852   2.103741     3.625926\n",
      "ETHOSCOPE_302 - Fly 20   0.814815  -0.703537     0.601852\n",
      "\n",
      "==================================================\n",
      "\n",
      "--- Average Change (Delta) across all flies ---\n",
      "Delta_24h: 1.09 ± 0.39 hours\n",
      "Delta_Day: -0.37 ± 0.21 hours\n",
      "Delta_Night: 0.81 ± 0.28 hours\n"
     ]
    }
   ],
   "source": [
    "#DELTA\n",
    "\n",
    "# 1. Ensure we have the merged paired data\n",
    "combined = pd.merge(baseline_stats, stim_stats, on='Fly_Label')\n",
    "\n",
    "# 2. Calculate the Delta (Stimulus - Baseline) for each fly\n",
    "combined['Delta_24h'] = combined['Stim_Sleep_24h'] - combined['Base_Sleep_24h']\n",
    "combined['Delta_Day'] = combined['Stim_Day_12h'] - combined['Base_Day_12h']\n",
    "combined['Delta_Night'] = combined['Stim_Night_12h'] - combined['Base_Night_12h']\n",
    "\n",
    "# 3. Print the Delta for each individual fly\n",
    "print(\"--- Delta Sleep (Stimulus - Baseline) per Fly ---\")\n",
    "delta_table = combined[['Fly_Label', 'Delta_24h', 'Delta_Day', 'Delta_Night']]\n",
    "print(delta_table.to_string(index=False))\n",
    "print(\"\\n\" + \"=\"*50 + \"\\n\")\n",
    "\n",
    "# 4. Calculate and print the group averages\n",
    "print(\"--- Average Change (Delta) across all flies ---\")\n",
    "avg_delta = delta_table[['Delta_24h', 'Delta_Day', 'Delta_Night']].mean()\n",
    "sem_delta = delta_table[['Delta_24h', 'Delta_Day', 'Delta_Night']].sem()\n",
    "\n",
    "for metric in ['Delta_24h', 'Delta_Day', 'Delta_Night']:\n",
    "    print(f\"{metric}: {avg_delta[metric]:.2f} ± {sem_delta[metric]:.2f} hours\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "id": "ff242cdd-721c-4e06-a9a6-91591589fe8a",
   "metadata": {},
   "outputs": [],
   "source": [
    "#export to csv\n",
    "delta_table['Condition'] = 'Red'\n",
    "delta_table.to_csv('delta_11H_phase6.csv', index=False)"
   ]
  }
 ],
 "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.12.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
