{ "cells": [ { "cell_type": "markdown", "id": "header", "metadata": {}, "source": [ "# Sound production in philodoptera\n", "\n", "Stridulation in crickets (e.g. [Pholidoptera littoralis](https://www.orthoptera.ch/wiki/arten/ensifera/tettigoniinae/item/pholidoptera-littoralis)) is a great animal model to study motor control/ sound production. Below is a tutorial on how we can create a `trials.nc`. Note that we have a video, audio and DeepLabCut pose file, meaning we can look at **movement** and **sound** features in the GUI!" ] }, { "cell_type": "markdown", "id": "7160e4af", "metadata": {}, "source": [ "\n", "\n", "\n", "Made in Slovenia, 2025." ] }, { "cell_type": "code", "execution_count": 10, "id": "imports", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "The autoreload extension is already loaded. To reload it, use:\n", " %reload_ext autoreload\n" ] } ], "source": [ "%load_ext autoreload\n", "%autoreload 2\n", "\n", "import pandas as pd\n", "from pathlib import Path\n", "from audioio import AudioLoader\n", "from movement.io import load_poses\n", "from movement.kinematics import compute_velocity, compute_speed, compute_acceleration\n", "\n", "import ethograph as eto\n", "from ethograph.utils.download import download_example_dataset\n", "from ethograph.io.nwb_alignment import align_media_per_trial" ] }, { "cell_type": "markdown", "id": "093c813f", "metadata": {}, "source": [ "### Download example data" ] }, { "cell_type": "code", "execution_count": 2, "id": "download", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Downloading philodoptera.nc... (1/4)\n", "Downloading philodoptera.mp4... (2/4)\n", "Downloading philodoptera.wav... (3/4)\n", " philodoptera.csv (4/4)\n", "\n", "data_folder: d:\\Akseli\\Code\\ethograph\\data\\philodoptera\n" ] } ], "source": [ "try:\n", " _here = Path(__vsc_ipynb_file__).parent\n", "except NameError:\n", " _here = Path().resolve()\n", "\n", "data_folder = _here.parent / \"data\" / \"philodoptera\"\n", "download_example_dataset(\"philodoptera\", data_folder)\n", "print(f\"\\ndata_folder: {data_folder}\")" ] }, { "cell_type": "markdown", "id": "2350b3f0", "metadata": {}, "source": [ "### Build NWB alignment" ] }, { "cell_type": "code", "execution_count": null, "id": "build_alignment", "metadata": {}, "outputs": [], "source": [ "video_path = data_folder / \"philodoptera.mp4\"\n", "audio_path = data_folder / \"philodoptera.wav\"\n", "poses_csv_path = data_folder / \"philodoptera.csv\"\n", "fps = 240\n", "\n", "# Probe audio sample rate from file\n", "with AudioLoader(str(audio_path)) as f:\n", " audio_sr = f.rate\n", "\n", "# Single-session dataset: one row in the session table\n", "session_table = pd.DataFrame({\n", " \"trial\": [\"session\"],\n", " \"video_0\": [str(video_path)],\n", " \"audio_0\": [str(audio_path)],\n", " \"pose_0\": [str(poses_csv_path)],\n", "})\n", "\n", "nwb_path = data_folder / \".ethograph\" / \"alignment.nwb\"\n", "align_media_per_trial(\n", " trial_table=session_table,\n", " stream_rates={\"video\": float(fps), \"audio\": float(audio_sr), \"pose\": float(fps)},\n", " output_path=nwb_path,\n", " pose_fps=float(fps),\n", ")" ] }, { "cell_type": "markdown", "id": "create_ds_header", "metadata": {}, "source": [ "### Create dataset" ] }, { "cell_type": "code", "execution_count": 7, "id": "create_ds", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Saved to d:\\Akseli\\Code\\ethograph\\data\\philodoptera\\philodoptera.nc\n" ] } ], "source": [ "# Load pose data and compute kinematics\n", "ds = load_poses.from_dlc_file(poses_csv_path, fps=fps)\n", "ds[\"velocity\"] = compute_velocity(ds.position)\n", "ds[\"speed\"] = compute_speed(ds.position)\n", "ds[\"acceleration\"] = compute_acceleration(ds.position)\n", "\n", "ds[\"individuals\"] = [\"Pholidoptera_littoralis_1\"]\n", "ds.attrs[\"Recording info\"] = (\n", " \"This cricket species Pholidoptera littoralis was recorded on a field trip \"\n", " \"in Slovenia in 2025. The video was recorded with an iPhone and the audio \"\n", " \"with a Zoom recorder. Synchronization may not be perfect.\"\n", ")\n", "\n", "\n", "ds.to_netcdf(data_folder / \"philodoptera.nc\")\n", "print(f\"Saved to {data_folder / 'philodoptera.nc'}\")" ] }, { "cell_type": "code", "execution_count": null, "id": "75e603c9", "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "ethograph", "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.13" } }, "nbformat": 4, "nbformat_minor": 5 }