{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "(target-dj-fetching-data)=\n", "# DataJoint pipeline: Fetching data as DataFrames\n", "\n", ":::{important}\n", "This guide assumes you have a [DataJoint pipeline deployed](target-dj-pipeline-deployment) with [data already ingested](target-dj-data-ingestion-processing).\n", ":::\n", "\n", "This guide builds upon the [Querying data](target-dj-querying-data) guide and provides further examples on fetching various kinds of data as `pandas.DataFrames` from the [Aeon DataJoint pipeline](target-aeon-dj-pipeline).\n", "\n", "You can also run this notebook online at [`works.datajoint.com`](https://works.datajoint.com/) using the following credentials:\n", " - Username: aeondemo\n", " - Password: aeon_djworks \n", "\n", "To access it, go to the Notebook tab at the top and in the File Browser on the left, navigate to `ucl-swc_aeon > docs > examples`, where this notebook `dj_fetching_data.ipynb` is located.\n", "\n", ":::{note}\n", "The examples here use the _social_ period of the [social0.2-aeon4](target-full-datasets) dataset.\n", "Since the social period spans 2 weeks, we limit retrieval to the first 3 days to keep the examples concise.\n", "\n", "If you are using a different dataset, be sure to replace the experiment name and parameters in the code below accordingly.\n", ":::" ] }, { "cell_type": "markdown", "metadata": { "vscode": { "languageId": "plaintext" } }, "source": [ "## Import libraries and define variables and helper functions" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from datetime import datetime\n", "import warnings\n", "\n", "import numpy as np\n", "import pandas as pd\n", "\n", "from aeon.dj_pipeline import acquisition, streams, subject, tracking\n", "from aeon.dj_pipeline.analysis.block_analysis import (\n", " Block,\n", " BlockAnalysis,\n", " BlockSubjectAnalysis,\n", " get_foraging_bouts,\n", ")" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "def ensure_ts_arr_datetime(array):\n", " \"\"\"Ensure array is a numpy array of datetime64[ns] type.\"\"\"\n", " if len(array) == 0:\n", " return np.array([], dtype=\"datetime64[ns]\")\n", " else:\n", " return np.array(array, dtype=\"datetime64[ns]\")\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "exp = {\n", " \"name\": \"social0.2-aeon4\",\n", " \"presocial_start\": \"2024-01-31 11:00:00\",\n", " \"presocial_end\": \"2024-02-08 15:00:00\",\n", " \"social_start\": \"2024-02-09 17:00:00\",\n", " \"social_end\": \"2024-02-23 12:00:00\",\n", " \"postsocial_start\": \"2024-02-25 18:00:00\",\n", " \"postsocial_end\": \"2024-03-02 13:00:00\",\n", "}\n", "key = {\"experiment_name\": exp[\"name\"]}\n", "# Define periods\n", "periods = {\n", " \"presocial\": (exp[\"presocial_start\"], exp[\"presocial_end\"]),\n", " \"social\": (exp[\"social_start\"], exp[\"social_end\"]),\n", " \"postsocial\": (exp[\"postsocial_start\"], exp[\"postsocial_end\"]),\n", "}\n", "# Select the social period and limit to first 3 days for brevity\n", "period_name = \"social\"\n", "start = periods[period_name][0]\n", "start_dt = datetime.strptime(start, \"%Y-%m-%d %H:%M:%S\")\n", "end_dt = start_dt + pd.Timedelta(days=3)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Patch data\n", "\n", "In this section, we will fetch [foraging patch](target-foraging-patch)-related data for each {term}`Block`.\n", "The data includes:\n", "- **patch information**: wheel timestamps, patch rate, and patch offset for each block\n", "- **subject patch data**: subjects' interactions with patches, including information on their presence in patches (duration, timestamps, RFID detections), pellet consumption (count, timestamps), and wheel movement (distance travelled)\n", "- **subject patch preferences**: preferences of subjects for different patches" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [], "source": [ "def load_subject_patch_data(\n", " key: dict[str, str], period_start: str, period_end: str\n", ") -> tuple[pd.DataFrame, pd.DataFrame, pd.DataFrame]:\n", " \"\"\"Loads subject patch data for a specified time period.\n", "\n", " Args:\n", " key (dict): The key to filter the subject patch data.\n", " period_start (str): The start time for the period.\n", " period_end (str): The end time for the period.\n", "\n", " Returns:\n", " tuple: A tuple containing:\n", " - patch_info (pd.DataFrame): Information about patches.\n", " - block_subject_patch_data (pd.DataFrame): Data for the specified period.\n", " - block_subject_patch_pref (pd.DataFrame): Preference data for the specified period.\n", " \"\"\"\n", " patch_info = (\n", " BlockAnalysis.Patch()\n", " & key\n", " & f\"block_start >= '{period_start}'\"\n", " & f\"block_start <= '{period_end}'\"\n", " ).fetch(\n", " \"block_start\",\n", " \"patch_name\",\n", " \"patch_rate\",\n", " \"patch_offset\",\n", " \"wheel_timestamps\",\n", " as_dict=True,\n", " )\n", "\n", " block_subject_patch_data = (\n", " BlockSubjectAnalysis.Patch()\n", " & key\n", " & f\"block_start >= '{period_start}'\"\n", " & f\"block_start <= '{period_end}'\"\n", " ).fetch(format=\"frame\")\n", "\n", " block_subject_patch_pref = (\n", " BlockSubjectAnalysis.Preference()\n", " & key\n", " & f\"block_start >= '{period_start}'\"\n", " & f\"block_start <= '{period_end}'\"\n", " ).fetch(format=\"frame\")\n", "\n", " if patch_info:\n", " patch_info = pd.DataFrame(patch_info)\n", "\n", " if isinstance(block_subject_patch_data, pd.DataFrame) and not block_subject_patch_data.empty:\n", " block_subject_patch_data.reset_index(inplace=True)\n", "\n", " if isinstance(block_subject_patch_pref, pd.DataFrame) and not block_subject_patch_pref.empty:\n", " block_subject_patch_pref.reset_index(inplace=True)\n", "\n", " return patch_info, block_subject_patch_data, block_subject_patch_pref" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [], "source": [ "block_patch_info, block_subject_patch_data, block_subject_patch_pref = load_subject_patch_data(key, start_dt, end_dt)\n", "\n", "# Drop NaNs in preference columns\n", "block_subject_patch_pref = block_subject_patch_pref.dropna(subset=[\"final_preference_by_time\", \"final_preference_by_wheel\"])\n", "\n", "# Validate subject count for pre/post-social blocks\n", "if period_name in [\"presocial\", \"postsocial\"] and not block_subject_patch_data.empty:\n", " n_subjects = block_subject_patch_data.groupby(\"block_start\")[\"subject_name\"].nunique()\n", " if (n_subjects != 1).any():\n", " warnings.warn(\n", " f\"{exp['name']} {period_name} blocks have >1 subject. Data may need cleaning.\"\n", " )\n", "\n", "# Ensure timestamp arrays are datetime64[ns]\n", "for col in [\"pellet_timestamps\", \"in_patch_rfid_timestamps\", \"in_patch_timestamps\"]:\n", " if col in block_subject_patch_data.columns:\n", " block_subject_patch_data[col] = block_subject_patch_data[col].apply(ensure_ts_arr_datetime)" ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
block_startpatch_namewheel_timestampspatch_ratepatch_offset
02024-02-09 18:19:04.000000Patch1[2024-02-09T18:19:04.000000000, 2024-02-09T18:...0.010075.0
12024-02-09 18:19:04.000000Patch2[2024-02-09T18:19:04.000000000, 2024-02-09T18:...0.002075.0
22024-02-09 18:19:04.000000Patch3[2024-02-09T18:19:04.000000000, 2024-02-09T18:...0.003375.0
32024-02-09 20:07:25.041984Patch1[2024-02-09T20:07:25.060000000, 2024-02-09T20:...0.002075.0
42024-02-09 20:07:25.041984Patch2[2024-02-09T20:07:25.060000000, 2024-02-09T20:...0.003375.0
..................
1092024-02-12 14:31:02.005984Patch2[2024-02-12T14:31:02.020000000, 2024-02-12T14:...0.003375.0
1102024-02-12 14:31:02.005984Patch3[2024-02-12T14:31:02.020000000, 2024-02-12T14:...0.010075.0
1112024-02-12 16:53:14.000000Patch1[2024-02-12T16:53:14.000000000, 2024-02-12T16:...0.002075.0
1122024-02-12 16:53:14.000000Patch2[2024-02-12T16:53:14.000000000, 2024-02-12T16:...0.010075.0
1132024-02-12 16:53:14.000000Patch3[2024-02-12T16:53:14.000000000, 2024-02-12T16:...0.003375.0
\n", "

114 rows × 5 columns

\n", "
" ], "text/plain": [ " block_start patch_name \\\n", "0 2024-02-09 18:19:04.000000 Patch1 \n", "1 2024-02-09 18:19:04.000000 Patch2 \n", "2 2024-02-09 18:19:04.000000 Patch3 \n", "3 2024-02-09 20:07:25.041984 Patch1 \n", "4 2024-02-09 20:07:25.041984 Patch2 \n", ".. ... ... \n", "109 2024-02-12 14:31:02.005984 Patch2 \n", "110 2024-02-12 14:31:02.005984 Patch3 \n", "111 2024-02-12 16:53:14.000000 Patch1 \n", "112 2024-02-12 16:53:14.000000 Patch2 \n", "113 2024-02-12 16:53:14.000000 Patch3 \n", "\n", " wheel_timestamps patch_rate \\\n", "0 [2024-02-09T18:19:04.000000000, 2024-02-09T18:... 0.0100 \n", "1 [2024-02-09T18:19:04.000000000, 2024-02-09T18:... 0.0020 \n", "2 [2024-02-09T18:19:04.000000000, 2024-02-09T18:... 0.0033 \n", "3 [2024-02-09T20:07:25.060000000, 2024-02-09T20:... 0.0020 \n", "4 [2024-02-09T20:07:25.060000000, 2024-02-09T20:... 0.0033 \n", ".. ... ... \n", "109 [2024-02-12T14:31:02.020000000, 2024-02-12T14:... 0.0033 \n", "110 [2024-02-12T14:31:02.020000000, 2024-02-12T14:... 0.0100 \n", "111 [2024-02-12T16:53:14.000000000, 2024-02-12T16:... 0.0020 \n", "112 [2024-02-12T16:53:14.000000000, 2024-02-12T16:... 0.0100 \n", "113 [2024-02-12T16:53:14.000000000, 2024-02-12T16:... 0.0033 \n", "\n", " patch_offset \n", "0 75.0 \n", "1 75.0 \n", "2 75.0 \n", "3 75.0 \n", "4 75.0 \n", ".. ... \n", "109 75.0 \n", "110 75.0 \n", "111 75.0 \n", "112 75.0 \n", "113 75.0 \n", "\n", "[114 rows x 5 columns]" ] }, "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ "block_patch_info" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
experiment_nameblock_startpatch_namesubject_namein_patch_timestampsin_patch_timein_patch_rfid_timestampspellet_countpellet_timestampspatch_thresholdwheel_cumsum_distance_travelledperiod
0social0.2-aeon42024-02-09 18:19:04Patch1BAA-1104048[2024-02-09T18:26:44.600000000, 2024-02-09T18:...756.60[2024-02-09T18:26:45.736672000, 2024-02-09T18:...39[2024-02-09T18:26:50.373504000, 2024-02-09T18:...[125.10144062824004, 125.98842043772429, 133.9...[-0.0, 0.004602223261072957, 0.007670372101788...social
1social0.2-aeon42024-02-09 18:19:04Patch1BAA-1104049[2024-02-09T18:21:10.200000000, 2024-02-09T18:...570.18[2024-02-09T18:21:11.452832000, 2024-02-09T18:...26[2024-02-09T18:28:57.907488000, 2024-02-09T18:...[75.07162358109204, 186.27023735234684, 135.82...[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ...social
2social0.2-aeon42024-02-09 18:19:04Patch2BAA-1104048[2024-02-09T18:20:10.400000000, 2024-02-09T18:...123.32[2024-02-09T18:20:12.097312000, 2024-02-09T18:...0[][][-0.0, -0.004602223261073846, -0.0015340744203...social
3social0.2-aeon42024-02-09 18:19:04Patch2BAA-1104049[2024-02-09T18:20:54.600000000, 2024-02-09T18:...226.80[2024-02-09T18:21:30.375328000, 2024-02-09T18:...3[2024-02-09T18:52:14.199488000, 2024-02-09T19:...[1069.4286592499257, 694.8095229017808, 278.84...[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ...social
4social0.2-aeon42024-02-09 18:19:04Patch3BAA-1104048[2024-02-09T18:20:03.940000000, 2024-02-09T18:...138.78[2024-02-09T18:25:59.113504000, 2024-02-09T18:...1[2024-02-09T19:30:22.688480000][331.8480024096391][0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ...social
.......................................
223social0.2-aeon42024-02-12 16:53:14Patch1BAA-1104049[2024-02-12T17:01:34.760000000, 2024-02-12T17:...94.98[2024-02-12T17:01:35.372416000, 2024-02-12T17:...0[][][-0.0, -0.00920444652214547, -0.00613629768143...social
224social0.2-aeon42024-02-12 16:53:14Patch2BAA-1104048[2024-02-12T16:58:52.540000000, 2024-02-12T16:...627.76[2024-02-12T16:58:53.758496000, 2024-02-12T16:...18[2024-02-12T17:01:47.607488000, 2024-02-12T17:...[128.88388967189582, 98.29740841703715, 138.54...[-0.0, 0.0030681488407182655, 0.00306814884071...social
225social0.2-aeon42024-02-12 16:53:14Patch2BAA-1104049[2024-02-12T16:53:55.360000000, 2024-02-12T16:...1215.12[2024-02-12T16:53:56.698656000, 2024-02-12T16:...34[2024-02-12T16:57:31.338496000, 2024-02-12T16:...[245.09652119007265, 137.19851472663964, 129.5...[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ...social
226social0.2-aeon42024-02-12 16:53:14Patch3BAA-1104048[2024-02-12T16:58:45.920000000, 2024-02-12T16:...101.68[2024-02-12T16:58:47.270432000, 2024-02-12T16:...0[][][-0.0, 0.0, -0.006136297681431202, -0.00460222...social
227social0.2-aeon42024-02-12 16:53:14Patch3BAA-1104049[2024-02-12T17:01:20.200000000, 2024-02-12T17:...48.12[2024-02-12T17:01:22.861888000, 2024-02-12T17:...0[][][0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ...social
\n", "

228 rows × 12 columns

\n", "
" ], "text/plain": [ " experiment_name block_start patch_name subject_name \\\n", "0 social0.2-aeon4 2024-02-09 18:19:04 Patch1 BAA-1104048 \n", "1 social0.2-aeon4 2024-02-09 18:19:04 Patch1 BAA-1104049 \n", "2 social0.2-aeon4 2024-02-09 18:19:04 Patch2 BAA-1104048 \n", "3 social0.2-aeon4 2024-02-09 18:19:04 Patch2 BAA-1104049 \n", "4 social0.2-aeon4 2024-02-09 18:19:04 Patch3 BAA-1104048 \n", ".. ... ... ... ... \n", "223 social0.2-aeon4 2024-02-12 16:53:14 Patch1 BAA-1104049 \n", "224 social0.2-aeon4 2024-02-12 16:53:14 Patch2 BAA-1104048 \n", "225 social0.2-aeon4 2024-02-12 16:53:14 Patch2 BAA-1104049 \n", "226 social0.2-aeon4 2024-02-12 16:53:14 Patch3 BAA-1104048 \n", "227 social0.2-aeon4 2024-02-12 16:53:14 Patch3 BAA-1104049 \n", "\n", " in_patch_timestamps in_patch_time \\\n", "0 [2024-02-09T18:26:44.600000000, 2024-02-09T18:... 756.60 \n", "1 [2024-02-09T18:21:10.200000000, 2024-02-09T18:... 570.18 \n", "2 [2024-02-09T18:20:10.400000000, 2024-02-09T18:... 123.32 \n", "3 [2024-02-09T18:20:54.600000000, 2024-02-09T18:... 226.80 \n", "4 [2024-02-09T18:20:03.940000000, 2024-02-09T18:... 138.78 \n", ".. ... ... \n", "223 [2024-02-12T17:01:34.760000000, 2024-02-12T17:... 94.98 \n", "224 [2024-02-12T16:58:52.540000000, 2024-02-12T16:... 627.76 \n", "225 [2024-02-12T16:53:55.360000000, 2024-02-12T16:... 1215.12 \n", "226 [2024-02-12T16:58:45.920000000, 2024-02-12T16:... 101.68 \n", "227 [2024-02-12T17:01:20.200000000, 2024-02-12T17:... 48.12 \n", "\n", " in_patch_rfid_timestamps pellet_count \\\n", "0 [2024-02-09T18:26:45.736672000, 2024-02-09T18:... 39 \n", "1 [2024-02-09T18:21:11.452832000, 2024-02-09T18:... 26 \n", "2 [2024-02-09T18:20:12.097312000, 2024-02-09T18:... 0 \n", "3 [2024-02-09T18:21:30.375328000, 2024-02-09T18:... 3 \n", "4 [2024-02-09T18:25:59.113504000, 2024-02-09T18:... 1 \n", ".. ... ... \n", "223 [2024-02-12T17:01:35.372416000, 2024-02-12T17:... 0 \n", "224 [2024-02-12T16:58:53.758496000, 2024-02-12T16:... 18 \n", "225 [2024-02-12T16:53:56.698656000, 2024-02-12T16:... 34 \n", "226 [2024-02-12T16:58:47.270432000, 2024-02-12T16:... 0 \n", "227 [2024-02-12T17:01:22.861888000, 2024-02-12T17:... 0 \n", "\n", " pellet_timestamps \\\n", "0 [2024-02-09T18:26:50.373504000, 2024-02-09T18:... \n", "1 [2024-02-09T18:28:57.907488000, 2024-02-09T18:... \n", "2 [] \n", "3 [2024-02-09T18:52:14.199488000, 2024-02-09T19:... \n", "4 [2024-02-09T19:30:22.688480000] \n", ".. ... \n", "223 [] \n", "224 [2024-02-12T17:01:47.607488000, 2024-02-12T17:... \n", "225 [2024-02-12T16:57:31.338496000, 2024-02-12T16:... \n", "226 [] \n", "227 [] \n", "\n", " patch_threshold \\\n", "0 [125.10144062824004, 125.98842043772429, 133.9... \n", "1 [75.07162358109204, 186.27023735234684, 135.82... \n", "2 [] \n", "3 [1069.4286592499257, 694.8095229017808, 278.84... \n", "4 [331.8480024096391] \n", ".. ... \n", "223 [] \n", "224 [128.88388967189582, 98.29740841703715, 138.54... \n", "225 [245.09652119007265, 137.19851472663964, 129.5... \n", "226 [] \n", "227 [] \n", "\n", " wheel_cumsum_distance_travelled period \n", "0 [-0.0, 0.004602223261072957, 0.007670372101788... social \n", "1 [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ... social \n", "2 [-0.0, -0.004602223261073846, -0.0015340744203... social \n", "3 [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ... social \n", "4 [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ... social \n", ".. ... ... \n", "223 [-0.0, -0.00920444652214547, -0.00613629768143... social \n", "224 [-0.0, 0.0030681488407182655, 0.00306814884071... social \n", "225 [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ... social \n", "226 [-0.0, 0.0, -0.006136297681431202, -0.00460222... social \n", "227 [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ... social \n", "\n", "[228 rows x 12 columns]" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "block_subject_patch_data" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
experiment_nameblock_startpatch_namesubject_namecumulative_preference_by_wheelcumulative_preference_by_timerunning_preference_by_timerunning_preference_by_wheelfinal_preference_by_wheelfinal_preference_by_timeperiod
0social0.2-aeon42024-02-09 18:19:04Patch1BAA-1104048[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ...[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ...[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ...[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ...0.7589470.742711social
1social0.2-aeon42024-02-09 18:19:04Patch1BAA-1104049[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ...[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ...[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ...[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ...0.5481700.574604social
2social0.2-aeon42024-02-09 18:19:04Patch2BAA-1104048[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ...[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ...[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ...[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ...0.0962010.121056social
3social0.2-aeon42024-02-09 18:19:04Patch2BAA-1104049[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ...[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ...[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ...[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ...0.2513080.228560social
4social0.2-aeon42024-02-09 18:19:04Patch3BAA-1104048[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ...[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ...[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ...[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ...0.1448520.136232social
....................................
223social0.2-aeon42024-02-12 16:53:14Patch1BAA-1104049[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ...[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ...[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ...[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ...0.0380670.069930social
224social0.2-aeon42024-02-12 16:53:14Patch2BAA-1104048[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ...[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ...[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ...[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ...0.8318080.778163social
225social0.2-aeon42024-02-12 16:53:14Patch2BAA-1104049[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ...[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ...[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ...[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ...0.9555880.894642social
226social0.2-aeon42024-02-12 16:53:14Patch3BAA-1104048[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ...[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ...[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ...[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ...0.1620960.126041social
227social0.2-aeon42024-02-12 16:53:14Patch3BAA-1104049[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ...[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ...[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ...[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ...0.0063450.035429social
\n", "

162 rows × 11 columns

\n", "
" ], "text/plain": [ " experiment_name block_start patch_name subject_name \\\n", "0 social0.2-aeon4 2024-02-09 18:19:04 Patch1 BAA-1104048 \n", "1 social0.2-aeon4 2024-02-09 18:19:04 Patch1 BAA-1104049 \n", "2 social0.2-aeon4 2024-02-09 18:19:04 Patch2 BAA-1104048 \n", "3 social0.2-aeon4 2024-02-09 18:19:04 Patch2 BAA-1104049 \n", "4 social0.2-aeon4 2024-02-09 18:19:04 Patch3 BAA-1104048 \n", ".. ... ... ... ... \n", "223 social0.2-aeon4 2024-02-12 16:53:14 Patch1 BAA-1104049 \n", "224 social0.2-aeon4 2024-02-12 16:53:14 Patch2 BAA-1104048 \n", "225 social0.2-aeon4 2024-02-12 16:53:14 Patch2 BAA-1104049 \n", "226 social0.2-aeon4 2024-02-12 16:53:14 Patch3 BAA-1104048 \n", "227 social0.2-aeon4 2024-02-12 16:53:14 Patch3 BAA-1104049 \n", "\n", " cumulative_preference_by_wheel \\\n", "0 [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ... \n", "1 [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ... \n", "2 [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ... \n", "3 [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ... \n", "4 [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ... \n", ".. ... \n", "223 [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ... \n", "224 [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ... \n", "225 [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ... \n", "226 [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ... \n", "227 [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ... \n", "\n", " cumulative_preference_by_time \\\n", "0 [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ... \n", "1 [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ... \n", "2 [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ... \n", "3 [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ... \n", "4 [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ... \n", ".. ... \n", "223 [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ... \n", "224 [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ... \n", "225 [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ... \n", "226 [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ... \n", "227 [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ... \n", "\n", " running_preference_by_time \\\n", "0 [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ... \n", "1 [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ... \n", "2 [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ... \n", "3 [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ... \n", "4 [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ... \n", ".. ... \n", "223 [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ... \n", "224 [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ... \n", "225 [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ... \n", "226 [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ... \n", "227 [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ... \n", "\n", " running_preference_by_wheel \\\n", "0 [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ... \n", "1 [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ... \n", "2 [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ... \n", "3 [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ... \n", "4 [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ... \n", ".. ... \n", "223 [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ... \n", "224 [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ... \n", "225 [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ... \n", "226 [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ... \n", "227 [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ... \n", "\n", " final_preference_by_wheel final_preference_by_time period \n", "0 0.758947 0.742711 social \n", "1 0.548170 0.574604 social \n", "2 0.096201 0.121056 social \n", "3 0.251308 0.228560 social \n", "4 0.144852 0.136232 social \n", ".. ... ... ... \n", "223 0.038067 0.069930 social \n", "224 0.831808 0.778163 social \n", "225 0.955588 0.894642 social \n", "226 0.162096 0.126041 social \n", "227 0.006345 0.035429 social \n", "\n", "[162 rows x 11 columns]" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "block_subject_patch_pref" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Foraging bouts\n", "\n", "Here we will use the `block_analysis.get_foraging_bouts()` function to retrieve foraging bout data for each subject across all {term}`blocks `." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def load_foraging_bouts(\n", " key: dict[str, str], period_start: str, period_end: str\n", ") -> pd.DataFrame:\n", " \"\"\"Loads foraging bout data for blocks falling within a specified time period.\n", "\n", " Args:\n", " key (dict): Key to identify experiment data (e.g., {\"experiment_name\": \"Exp1\"}).\n", " period_start (str): Start datetime of the time period (format: '%Y-%m-%d %H:%M:%S').\n", " period_end (str): End datetime of the time period (format: '%Y-%m-%d %H:%M:%S').\n", "\n", " Returns:\n", " pd.DataFrame: Concatenated dataframe of foraging bouts for all matching blocks.\n", " Returns an empty dataframe with predefined columns if no data found.\n", " \"\"\"\n", " # Fetch block start times within the specified period\n", " blocks = (\n", " Block & key & f\"block_start >= '{period_start}'\" & f\"block_end <= '{period_end}'\"\n", " ).fetch(\"block_start\")\n", "\n", " # Retrieve foraging bouts for each block\n", " bouts = []\n", " for block_start in blocks:\n", " block_key = key | {\"block_start\": str(block_start)}\n", " bouts.append(get_foraging_bouts(block_key, min_pellets=1))\n", "\n", " # Return concatenated DataFrame or empty fallback\n", " if bouts:\n", " return pd.concat(bouts, ignore_index=True)\n", " else:\n", " return pd.DataFrame(\n", " columns=[\"start\", \"end\", \"n_pellets\", \"cum_wheel_dist\", \"subject\"]\n", " )\n", "\n", "# Load foraging bouts\n", "foraging_df = load_foraging_bouts(key, start_dt, end_dt)" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
startendn_pelletscum_wheel_distsubject
02024-02-09 18:26:07.2802024-02-09 18:27:51.4601458.105303BAA-1104048
12024-02-09 18:28:26.7202024-02-09 18:30:25.4401464.014558BAA-1104049
22024-02-09 18:36:49.7602024-02-09 18:38:21.3602240.621107BAA-1104049
32024-02-09 18:39:17.1802024-02-09 18:42:14.8807983.174489BAA-1104048
42024-02-09 18:43:02.4402024-02-09 18:44:35.4801247.676315BAA-1104049
..................
3272024-02-12 16:24:17.6602024-02-12 16:26:56.1603680.642741BAA-1104048
3282024-02-12 16:30:04.7402024-02-12 16:33:20.3003981.212408BAA-1104048
3292024-02-12 16:38:32.8402024-02-12 16:43:16.60032384.391929BAA-1104048
3302024-02-12 16:49:39.3802024-02-12 16:51:38.9201321.695406BAA-1104049
3312024-02-12 16:51:21.4402024-02-12 16:53:12.6402423.237326BAA-1104048
\n", "

332 rows × 5 columns

\n", "
" ], "text/plain": [ " start end n_pellets cum_wheel_dist \\\n", "0 2024-02-09 18:26:07.280 2024-02-09 18:27:51.460 1 458.105303 \n", "1 2024-02-09 18:28:26.720 2024-02-09 18:30:25.440 1 464.014558 \n", "2 2024-02-09 18:36:49.760 2024-02-09 18:38:21.360 2 240.621107 \n", "3 2024-02-09 18:39:17.180 2024-02-09 18:42:14.880 7 983.174489 \n", "4 2024-02-09 18:43:02.440 2024-02-09 18:44:35.480 1 247.676315 \n", ".. ... ... ... ... \n", "327 2024-02-12 16:24:17.660 2024-02-12 16:26:56.160 3 680.642741 \n", "328 2024-02-12 16:30:04.740 2024-02-12 16:33:20.300 3 981.212408 \n", "329 2024-02-12 16:38:32.840 2024-02-12 16:43:16.600 3 2384.391929 \n", "330 2024-02-12 16:49:39.380 2024-02-12 16:51:38.920 1 321.695406 \n", "331 2024-02-12 16:51:21.440 2024-02-12 16:53:12.640 2 423.237326 \n", "\n", " subject \n", "0 BAA-1104048 \n", "1 BAA-1104049 \n", "2 BAA-1104049 \n", "3 BAA-1104048 \n", "4 BAA-1104049 \n", ".. ... \n", "327 BAA-1104048 \n", "328 BAA-1104048 \n", "329 BAA-1104048 \n", "330 BAA-1104049 \n", "331 BAA-1104048 \n", "\n", "[332 rows x 5 columns]" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "foraging_df" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## RFID data\n", "\n", "In this experiment, each subject is implanted with a miniature RFID microchip.\n", "RFID readers are positioned at the [foraging patches](target-foraging-patch), [nest](target-nest), and [gate](target-habitat).\n", "\n", "We will fetch the RFID detection data at each reader across all {term}`chunks ` occurring within the first 3 days of the social period." ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [], "source": [ "def load_rfid_events(\n", " key: dict[str, str], period_start: str, period_end: str\n", ") -> pd.DataFrame:\n", " \"\"\"Loads RFID events data for chunks falling within a specified time period.\n", "\n", " Args:\n", " key (dict): Key to identify experiment data (e.g., {\"experiment_name\": \"Exp1\"}).\n", " period_start (str): Start datetime of the time period (format: '%Y-%m-%d %H:%M:%S').\n", " period_end (str): End datetime of the time period (format: '%Y-%m-%d %H:%M:%S').\n", "\n", " Returns:\n", " pd.DataFrame: DataFrame containing RFID events for the specified period.\n", " Returns an empty dataframe with predefined columns if no data found.\n", " \"\"\"\n", " # Fetch RFID events within the specified period\n", " rfid_events_df = (\n", " streams.RfidReader * streams.RfidReaderRfidEvents\n", " & key\n", " & f'chunk_start >= \"{period_start}\"'\n", " & f'chunk_start <= \"{period_end}\"'\n", " ).fetch(format=\"frame\")\n", "\n", " if rfid_events_df.empty or not isinstance(rfid_events_df, pd.DataFrame):\n", " # Return empty DataFrame with expected columns if no data found\n", " return pd.DataFrame(\n", " columns=[\n", " \"experiment_name\",\n", " \"chunk_start\",\n", " \"rfid_reader_name\",\n", " \"sample_count\",\n", " \"timestamps\",\n", " \"rfid\",\n", " ]\n", " )\n", "\n", " # Get subject details for RFID mapping\n", " subject_detail = subject.SubjectDetail.fetch(format=\"frame\")\n", " subject_detail.reset_index(inplace=True)\n", "\n", " # Create mapping from RFID to subject ID\n", " rfid_to_lab_id = dict(zip(subject_detail[\"lab_id\"], subject_detail[\"subject\"]))\n", "\n", " rfid_events_df[\"rfid\"] = [\n", " [rfid_to_lab_id.get(str(rfid)) for rfid in rfid_array]\n", " for rfid_array in rfid_events_df[\"rfid\"]\n", " ]\n", "\n", " # Extract experiment_name and chunk_start from the index before resetting\n", " rfid_events_df[\"experiment_name\"] = [idx[0] for idx in rfid_events_df.index]\n", " rfid_events_df[\"chunk_start\"] = [\n", " idx[3] for idx in rfid_events_df.index\n", " ] # Assuming chunk_start is at index 3\n", "\n", " # Reset the index and drop the index column\n", " rfid_events_df = rfid_events_df.reset_index(drop=True)\n", "\n", " # Reorder columns to put experiment_name first and chunk_start second\n", " cols = [\"experiment_name\", \"chunk_start\"] + [\n", " col\n", " for col in rfid_events_df.columns\n", " if col not in [\"experiment_name\", \"chunk_start\"]\n", " ]\n", " rfid_events_df = rfid_events_df[cols]\n", "\n", " return rfid_events_df\n", "\n", "# Load RFID data\n", "rfid_df = load_rfid_events(key, start_dt, end_dt)" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
experiment_namechunk_startrfid_reader_namesample_counttimestampsrfid
0social0.2-aeon42024-02-09 17:00:00Patch1Rfid844[2024-02-09T17:00:00.483007908, 2024-02-09T17:...[BAA-1104048, BAA-1104048, BAA-1104048, BAA-11...
1social0.2-aeon42024-02-09 18:00:00Patch1Rfid857[2024-02-09T18:01:41.768191814, 2024-02-09T18:...[BAA-1104049, BAA-1104048, BAA-1104048, BAA-11...
2social0.2-aeon42024-02-09 19:00:00Patch1Rfid1262[2024-02-09T19:04:08.140863895, 2024-02-09T19:...[BAA-1104048, BAA-1104048, BAA-1104048, BAA-11...
3social0.2-aeon42024-02-09 20:00:00Patch1Rfid301[2024-02-09T20:05:47.786528111, 2024-02-09T20:...[BAA-1104048, BAA-1104048, BAA-1104048, BAA-11...
4social0.2-aeon42024-02-09 21:00:00Patch1Rfid0[][]
.....................
433social0.2-aeon42024-02-12 13:00:00Patch3Rfid336[2024-02-12T13:05:10.713151932, 2024-02-12T13:...[BAA-1104048, BAA-1104048, BAA-1104048, BAA-11...
434social0.2-aeon42024-02-12 14:00:00Patch3Rfid323[2024-02-12T14:01:47.358272076, 2024-02-12T14:...[BAA-1104049, BAA-1104049, BAA-1104049, BAA-11...
435social0.2-aeon42024-02-12 15:00:00Patch3Rfid19[2024-02-12T15:12:24.588128090, 2024-02-12T15:...[BAA-1104049, BAA-1104049, BAA-1104049, BAA-11...
436social0.2-aeon42024-02-12 16:00:00Patch3Rfid139[2024-02-12T16:03:41.951839924, 2024-02-12T16:...[BAA-1104048, BAA-1104048, BAA-1104048, BAA-11...
437social0.2-aeon42024-02-12 17:00:00Patch3Rfid183[2024-02-12T17:01:05.555712223, 2024-02-12T17:...[BAA-1104048, BAA-1104048, BAA-1104048, BAA-11...
\n", "

438 rows × 6 columns

\n", "
" ], "text/plain": [ " experiment_name chunk_start rfid_reader_name sample_count \\\n", "0 social0.2-aeon4 2024-02-09 17:00:00 Patch1Rfid 844 \n", "1 social0.2-aeon4 2024-02-09 18:00:00 Patch1Rfid 857 \n", "2 social0.2-aeon4 2024-02-09 19:00:00 Patch1Rfid 1262 \n", "3 social0.2-aeon4 2024-02-09 20:00:00 Patch1Rfid 301 \n", "4 social0.2-aeon4 2024-02-09 21:00:00 Patch1Rfid 0 \n", ".. ... ... ... ... \n", "433 social0.2-aeon4 2024-02-12 13:00:00 Patch3Rfid 336 \n", "434 social0.2-aeon4 2024-02-12 14:00:00 Patch3Rfid 323 \n", "435 social0.2-aeon4 2024-02-12 15:00:00 Patch3Rfid 19 \n", "436 social0.2-aeon4 2024-02-12 16:00:00 Patch3Rfid 139 \n", "437 social0.2-aeon4 2024-02-12 17:00:00 Patch3Rfid 183 \n", "\n", " timestamps \\\n", "0 [2024-02-09T17:00:00.483007908, 2024-02-09T17:... \n", "1 [2024-02-09T18:01:41.768191814, 2024-02-09T18:... \n", "2 [2024-02-09T19:04:08.140863895, 2024-02-09T19:... \n", "3 [2024-02-09T20:05:47.786528111, 2024-02-09T20:... \n", "4 [] \n", ".. ... \n", "433 [2024-02-12T13:05:10.713151932, 2024-02-12T13:... \n", "434 [2024-02-12T14:01:47.358272076, 2024-02-12T14:... \n", "435 [2024-02-12T15:12:24.588128090, 2024-02-12T15:... \n", "436 [2024-02-12T16:03:41.951839924, 2024-02-12T16:... \n", "437 [2024-02-12T17:01:05.555712223, 2024-02-12T17:... \n", "\n", " rfid \n", "0 [BAA-1104048, BAA-1104048, BAA-1104048, BAA-11... \n", "1 [BAA-1104049, BAA-1104048, BAA-1104048, BAA-11... \n", "2 [BAA-1104048, BAA-1104048, BAA-1104048, BAA-11... \n", "3 [BAA-1104048, BAA-1104048, BAA-1104048, BAA-11... \n", "4 [] \n", ".. ... \n", "433 [BAA-1104048, BAA-1104048, BAA-1104048, BAA-11... \n", "434 [BAA-1104049, BAA-1104049, BAA-1104049, BAA-11... \n", "435 [BAA-1104049, BAA-1104049, BAA-1104049, BAA-11... \n", "436 [BAA-1104048, BAA-1104048, BAA-1104048, BAA-11... \n", "437 [BAA-1104048, BAA-1104048, BAA-1104048, BAA-11... \n", "\n", "[438 rows x 6 columns]" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ "rfid_df" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Position data\n", "\n", "In this section, we will fetch SLEAP position data (centroid only) from the `tracking.DenoisedTracking` table for each subject across all {term}`chunks ` occurring within the first 3 days of the social period.\n", "\n", ":::{note}\n", "The full pose data (all tracked body parts) can be fetched from the `tracking.SLEAPTracking.Part` table.\n", ":::" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " Querying data from 2024-02-09 17:00:00 to 2024-02-12 17:00:00...\n", " Retrieved 20211079 rows of position data\n" ] } ], "source": [ "def load_position_data(\n", " key: dict[str, str], period_start: str, period_end: str\n", ") -> pd.DataFrame:\n", " \"\"\"Loads position data (centroid tracking) for a specified time period.\n", "\n", " Args:\n", " key (dict): Key to identify experiment data (e.g., {\"experiment_name\": \"Exp1\"}).\n", " period_start (str): Start datetime of the time period.\n", " period_end (str): End datetime of the time period.\n", "\n", " Returns:\n", " pd.DataFrame: DataFrame containing position data for the specified period.\n", " Returns an empty DataFrame if no data found.\n", " \"\"\"\n", " try:\n", " print(f\" Querying data from {period_start} to {period_end}...\")\n", "\n", " # Create chunk restriction for the time period\n", " chunk_restriction = acquisition.create_chunk_restriction(\n", " key[\"experiment_name\"], period_start, period_end\n", " )\n", "\n", " # Fetch centroid tracking data for the specified period\n", " centroid_df = (\n", " streams.SpinnakerVideoSource * tracking.DenoisedTracking.Subject\n", " & key\n", " & {\"spinnaker_video_source_name\": \"CameraTop\"}\n", " & chunk_restriction\n", " ).fetch(format=\"frame\")\n", "\n", " centroid_df = centroid_df.reset_index()\n", " centroid_df = centroid_df.rename(\n", " columns={\n", " \"subject_name\": \"identity_name\",\n", " \"timestamps\": \"time\",\n", " \"subject_likelihood\": \"identity_likelihood\",\n", " }\n", " )\n", " centroid_df = centroid_df.explode(\n", " [\"time\", \"identity_likelihood\", \"x\", \"y\", \"likelihood\"]\n", " )\n", " centroid_df = centroid_df[\n", " [\n", " \"time\",\n", " \"experiment_name\",\n", " \"identity_name\",\n", " \"identity_likelihood\",\n", " \"x\",\n", " \"y\",\n", " \"likelihood\",\n", " ]\n", " ].set_index(\"time\")\n", "\n", " # Clean up the dataframe\n", " if isinstance(centroid_df, pd.DataFrame) and not centroid_df.empty:\n", " if \"spinnaker_video_source_name\" in centroid_df.columns:\n", " centroid_df.drop(columns=[\"spinnaker_video_source_name\"], inplace=True)\n", " print(f\" Retrieved {len(centroid_df)} rows of position data\")\n", " else:\n", " print(\" No data found for the specified period\")\n", "\n", " return centroid_df\n", "\n", " except Exception as e:\n", " print(\n", " f\" Error loading position data for {key['experiment_name']} ({period_start} \"\n", " f\"to {period_end}): {e}\"\n", " )\n", " return pd.DataFrame()\n", "\n", "\n", "# Load position data\n", "# If this takes too long, consider changing end_dt to an earlier time\n", "position_df = load_position_data(key, start_dt, end_dt).sort_index()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
experiment_nameidentity_nameidentity_likelihoodxylikelihood
time
2024-02-09 16:48:10.660social0.2-aeon4BAA-1104048NaN1280.208496550.0733640.971199
2024-02-09 16:48:10.660social0.2-aeon4BAA-11040490.1023431232.14624558.1130370.971199
2024-02-09 16:48:10.680social0.2-aeon4BAA-11040490.0214591282.991699552.2292480.985731
2024-02-09 16:48:10.680social0.2-aeon4BAA-1104048NaN1232.227051560.1209110.985731
2024-02-09 16:48:10.700social0.2-aeon4BAA-1104048NaN1283.058105552.2015380.963831
.....................
2024-02-12 17:59:59.460social0.2-aeon4BAA-11040490.9712211213.701416544.3001710.709776
2024-02-12 17:59:59.480social0.2-aeon4BAA-11040480.9970871211.169434531.4343870.709763
2024-02-12 17:59:59.480social0.2-aeon4BAA-11040490.9717621213.696045544.3092040.709763
2024-02-12 17:59:59.500social0.2-aeon4BAA-11040480.9968721211.168945531.433960.709618
2024-02-12 17:59:59.500social0.2-aeon4BAA-11040490.9714451213.696045544.3093260.709618
\n", "

20211079 rows × 6 columns

\n", "
" ], "text/plain": [ " experiment_name identity_name identity_likelihood \\\n", "time \n", "2024-02-09 16:48:10.660 social0.2-aeon4 BAA-1104048 NaN \n", "2024-02-09 16:48:10.660 social0.2-aeon4 BAA-1104049 0.102343 \n", "2024-02-09 16:48:10.680 social0.2-aeon4 BAA-1104049 0.021459 \n", "2024-02-09 16:48:10.680 social0.2-aeon4 BAA-1104048 NaN \n", "2024-02-09 16:48:10.700 social0.2-aeon4 BAA-1104048 NaN \n", "... ... ... ... \n", "2024-02-12 17:59:59.460 social0.2-aeon4 BAA-1104049 0.971221 \n", "2024-02-12 17:59:59.480 social0.2-aeon4 BAA-1104048 0.997087 \n", "2024-02-12 17:59:59.480 social0.2-aeon4 BAA-1104049 0.971762 \n", "2024-02-12 17:59:59.500 social0.2-aeon4 BAA-1104048 0.996872 \n", "2024-02-12 17:59:59.500 social0.2-aeon4 BAA-1104049 0.971445 \n", "\n", " x y likelihood \n", "time \n", "2024-02-09 16:48:10.660 1280.208496 550.073364 0.971199 \n", "2024-02-09 16:48:10.660 1232.14624 558.113037 0.971199 \n", "2024-02-09 16:48:10.680 1282.991699 552.229248 0.985731 \n", "2024-02-09 16:48:10.680 1232.227051 560.120911 0.985731 \n", "2024-02-09 16:48:10.700 1283.058105 552.201538 0.963831 \n", "... ... ... ... \n", "2024-02-12 17:59:59.460 1213.701416 544.300171 0.709776 \n", "2024-02-12 17:59:59.480 1211.169434 531.434387 0.709763 \n", "2024-02-12 17:59:59.480 1213.696045 544.309204 0.709763 \n", "2024-02-12 17:59:59.500 1211.168945 531.43396 0.709618 \n", "2024-02-12 17:59:59.500 1213.696045 544.309326 0.709618 \n", "\n", "[20211079 rows x 6 columns]" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "position_df" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Weight data\n", "\n", "A weighing scale integrated into the [nest](target-nest) records the weight data for each subject whenever a subject is alone in the nest. \n", "\n", "Here we will fetch the weight data for each subject across all {term}`chunks ` occurring within the first 3 days of the social period." ] }, { "cell_type": "code", "execution_count": 36, "metadata": {}, "outputs": [], "source": [ "def load_weight_data(\n", " key: dict[str, str], period_start: str, period_end: str\n", ") -> pd.DataFrame:\n", " \"\"\"Loads weight data for a specified time period.\n", "\n", " Args:\n", " key (dict): Key to identify experiment data (e.g., {\"experiment_name\": \"Exp1\"}).\n", " period_start (str): Start datetime of the time period (format: '%Y-%m-%d %H:%M:%S').\n", " period_end (str): End datetime of the time period (format: '%Y-%m-%d %H:%M:%S').\n", "\n", " Returns:\n", " pd.DataFrame: Weight data for the specified period.\n", " Returns an empty dataframe if no data found.\n", " \"\"\"\n", " try:\n", " weight_df = (\n", " acquisition.Environment.SubjectWeight\n", " & key\n", " & f\"chunk_start >= '{period_start}'\"\n", " & f\"chunk_start <= '{period_end}'\"\n", " ).proj(\"timestamps\", \"weight\", \"subject_id\").fetch(format=\"frame\")\n", " return weight_df if not weight_df.empty and isinstance(weight_df, pd.DataFrame) else pd.DataFrame()\n", " except Exception as e:\n", " print(\n", " f\"Error loading weight data for {key} from {period_start} to {period_end}: {e}\"\n", " )\n", " return pd.DataFrame()\n", "\n", "\n", "weight_df = load_weight_data(key, start_dt, end_dt)" ] }, { "cell_type": "code", "execution_count": 37, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
timestampsweightsubject_id
experiment_namechunk_start
social0.2-aeon42024-02-09 17:00:00[2024-02-09T17:12:29.800000191, 2024-02-09T17:...[23.522316, 23.522316, 23.522316, 23.522316, 2...[BAA-1104049, BAA-1104049, BAA-1104049, BAA-11...
2024-02-09 18:00:00[2024-02-09T18:07:53.019999981, 2024-02-09T18:...[25.6000004, 25.6000004, 25.6000004, 25.600000...[BAA-1104048, BAA-1104048, BAA-1104048, BAA-11...
2024-02-09 19:00:00[2024-02-09T19:04:08.159999847, 2024-02-09T19:...[27.4697571, 27.4697571, 27.4697571, 27.469757...[BAA-1104049, BAA-1104049, BAA-1104049, BAA-11...
2024-02-09 20:00:00[2024-02-09T20:20:22.920000076, 2024-02-09T20:...[31.3124409, 11.8549995][BAA-1104049, BAA-1104049]
2024-02-09 21:00:00[2024-02-09T21:08:21.480000019, 2024-02-09T21:...[21.3240242, 21.3240242, 21.3240242, 21.324024...[BAA-1104048, BAA-1104048, BAA-1104048, BAA-11...
............
2024-02-12 13:00:00[2024-02-12T13:01:20.599999905, 2024-02-12T13:...[28.2491455, 28.2541466, 28.2541466, 28.254146...[BAA-1104049, BAA-1104049, BAA-1104049, BAA-11...
2024-02-12 14:00:00[2024-02-12T14:15:02.300000191, 2024-02-12T14:...[28.2345123, 28.2345123, 28.2345123, 28.234512...[BAA-1104049, BAA-1104049, BAA-1104049, BAA-11...
2024-02-12 15:00:00[2024-02-12T15:12:41.400000095, 2024-02-12T15:...[32.1000023, 32.1000023, 32.1000023, 32.100002...[BAA-1104048, BAA-1104048, BAA-1104048, BAA-11...
2024-02-12 16:00:00[2024-02-12T16:12:17.960000038, 2024-02-12T16:...[30.8999977, 30.8999977, 30.8999977, 30.899997...[BAA-1104049, BAA-1104049, BAA-1104049, BAA-11...
2024-02-12 17:00:00[2024-02-12T17:02:20.840000153, 2024-02-12T17:...[30.1764622, 29.99049, 29.99049, 29.99049, 29....[BAA-1104049, BAA-1104048, BAA-1104048, BAA-11...
\n", "

73 rows × 3 columns

\n", "
" ], "text/plain": [ " timestamps \\\n", "experiment_name chunk_start \n", "social0.2-aeon4 2024-02-09 17:00:00 [2024-02-09T17:12:29.800000191, 2024-02-09T17:... \n", " 2024-02-09 18:00:00 [2024-02-09T18:07:53.019999981, 2024-02-09T18:... \n", " 2024-02-09 19:00:00 [2024-02-09T19:04:08.159999847, 2024-02-09T19:... \n", " 2024-02-09 20:00:00 [2024-02-09T20:20:22.920000076, 2024-02-09T20:... \n", " 2024-02-09 21:00:00 [2024-02-09T21:08:21.480000019, 2024-02-09T21:... \n", "... ... \n", " 2024-02-12 13:00:00 [2024-02-12T13:01:20.599999905, 2024-02-12T13:... \n", " 2024-02-12 14:00:00 [2024-02-12T14:15:02.300000191, 2024-02-12T14:... \n", " 2024-02-12 15:00:00 [2024-02-12T15:12:41.400000095, 2024-02-12T15:... \n", " 2024-02-12 16:00:00 [2024-02-12T16:12:17.960000038, 2024-02-12T16:... \n", " 2024-02-12 17:00:00 [2024-02-12T17:02:20.840000153, 2024-02-12T17:... \n", "\n", " weight \\\n", "experiment_name chunk_start \n", "social0.2-aeon4 2024-02-09 17:00:00 [23.522316, 23.522316, 23.522316, 23.522316, 2... \n", " 2024-02-09 18:00:00 [25.6000004, 25.6000004, 25.6000004, 25.600000... \n", " 2024-02-09 19:00:00 [27.4697571, 27.4697571, 27.4697571, 27.469757... \n", " 2024-02-09 20:00:00 [31.3124409, 11.8549995] \n", " 2024-02-09 21:00:00 [21.3240242, 21.3240242, 21.3240242, 21.324024... \n", "... ... \n", " 2024-02-12 13:00:00 [28.2491455, 28.2541466, 28.2541466, 28.254146... \n", " 2024-02-12 14:00:00 [28.2345123, 28.2345123, 28.2345123, 28.234512... \n", " 2024-02-12 15:00:00 [32.1000023, 32.1000023, 32.1000023, 32.100002... \n", " 2024-02-12 16:00:00 [30.8999977, 30.8999977, 30.8999977, 30.899997... \n", " 2024-02-12 17:00:00 [30.1764622, 29.99049, 29.99049, 29.99049, 29.... \n", "\n", " subject_id \n", "experiment_name chunk_start \n", "social0.2-aeon4 2024-02-09 17:00:00 [BAA-1104049, BAA-1104049, BAA-1104049, BAA-11... \n", " 2024-02-09 18:00:00 [BAA-1104048, BAA-1104048, BAA-1104048, BAA-11... \n", " 2024-02-09 19:00:00 [BAA-1104049, BAA-1104049, BAA-1104049, BAA-11... \n", " 2024-02-09 20:00:00 [BAA-1104049, BAA-1104049] \n", " 2024-02-09 21:00:00 [BAA-1104048, BAA-1104048, BAA-1104048, BAA-11... \n", "... ... \n", " 2024-02-12 13:00:00 [BAA-1104049, BAA-1104049, BAA-1104049, BAA-11... \n", " 2024-02-12 14:00:00 [BAA-1104049, BAA-1104049, BAA-1104049, BAA-11... \n", " 2024-02-12 15:00:00 [BAA-1104048, BAA-1104048, BAA-1104048, BAA-11... \n", " 2024-02-12 16:00:00 [BAA-1104049, BAA-1104049, BAA-1104049, BAA-11... \n", " 2024-02-12 17:00:00 [BAA-1104049, BAA-1104048, BAA-1104048, BAA-11... \n", "\n", "[73 rows x 3 columns]" ] }, "execution_count": 37, "metadata": {}, "output_type": "execute_result" } ], "source": [ "weight_df" ] } ], "metadata": { "kernelspec": { "display_name": "aeon", "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.11.11" } }, "nbformat": 4, "nbformat_minor": 2 }