From 10ff2a2a897ce271966737e9ed554ae185e8f068 Mon Sep 17 00:00:00 2001 From: Erik Tjong Kim Sang Date: Wed, 31 Mar 2021 17:26:26 +0200 Subject: [PATCH 1/5] first attempt --- ggir-use-case-1.ipynb | 147 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 147 insertions(+) create mode 100644 ggir-use-case-1.ipynb diff --git a/ggir-use-case-1.ipynb b/ggir-use-case-1.ipynb new file mode 100644 index 0000000..021602b --- /dev/null +++ b/ggir-use-case-1.ipynb @@ -0,0 +1,147 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# GGIR use case 1\n", + "\n", + "This use case requires the generation of three signals: rest, sleep and main bed period. All signals appear in a time signal between 12:00 noon and 12:00 next day. Each signal consists of two binary signals: period starts and period ends. For reference, there is a larger [description of this use case](https://github.com/sequgen/sequgen/issues/21) as well as a [visualization](https://cran.r-project.org/web/packages/GGIR/vignettes/GGIR.html#42_Output_part_4) of the time signals (click on the tab `4.2.3 visualisation_sleep.pdf`)." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 1. Time axis\n", + "\n", + "We model the time axis as a discrete list of minutes starting at 12\\*60 and ending at 36\\*60" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "\n", + "time_axis = np.arange(12*60, 36*60+1)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 2. Channels\n", + "\n", + "We start with a zero signal" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "from sequgen.deterministic.constant import constant\n", + "\n", + "channel_1 = constant(time_axis, 0)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Next, we define how many peaks we want, of what width and at what location" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "import random\n", + "from sequgen.dimension import Dimension\n", + "from sequgen.parameter_space import ParameterSpace\n", + "\n", + "def overlap(peaks):\n", + " peaks = [ peak for peak in sorted(peaks, key=lambda p:p['location']) ]\n", + " for i in range(0, len(peaks)-1):\n", + " if peaks[i]['location'] + peaks[i]['width'] >= peaks[i+1]['location']:\n", + " return(True)\n", + " return(False)\n", + "\n", + "iterations = random.randint(8,12)\n", + "peaks = []\n", + "start_time = time_axis[0]\n", + "while len(peaks) < iterations:\n", + " channel_1_parameter_space = ParameterSpace([\n", + " Dimension(\"location\", start_time, time_axis[-1]),\n", + " Dimension(\"width\", 10, 30),\n", + " ])\n", + " new_peak = channel_1_parameter_space.sample()\n", + " if not overlap(peaks+[new_peak]):\n", + " peaks.append(new_peak)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[{'location': 844.6832038089898, 'width': 28.86811004628262},\n", + " {'location': 1607.0707313223427, 'width': 27.832839252549945},\n", + " {'location': 1258.2611848841843, 'width': 17.969290975131415},\n", + " {'location': 1824.0410289912827, 'width': 25.339087800995205},\n", + " {'location': 1478.172539982449, 'width': 27.763902801091426},\n", + " {'location': 1674.2902318654558, 'width': 21.796208634427515},\n", + " {'location': 2138.1054655357575, 'width': 15.316048374888132},\n", + " {'location': 1073.2816828555506, 'width': 28.992778326933664},\n", + " {'location': 1281.2940788829344, 'width': 11.007700940398312},\n", + " {'location': 1428.6736924064255, 'width': 19.743754138923432}]" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "peaks" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "sequgen-notebooks", + "language": "python", + "name": "sequgen-notebooks" + }, + "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.7.5" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} From 6b5d4e79c9f1f2f5102d1aec0c1364e103635de6 Mon Sep 17 00:00:00 2001 From: Erik Tjong Kim Sang Date: Thu, 1 Apr 2021 21:38:10 +0200 Subject: [PATCH 2/5] built signal and plot --- ggir-use-case-1.ipynb | 218 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 177 insertions(+), 41 deletions(-) diff --git a/ggir-use-case-1.ipynb b/ggir-use-case-1.ipynb index 021602b..027a2e6 100644 --- a/ggir-use-case-1.ipynb +++ b/ggir-use-case-1.ipynb @@ -35,7 +35,7 @@ "source": [ "## 2. Channels\n", "\n", - "We start with a zero signal" + "We define how many peaks we want, of what width and at what location" ] }, { @@ -44,75 +44,211 @@ "metadata": {}, "outputs": [], "source": [ - "from sequgen.deterministic.constant import constant\n", + "import random\n", + "from sequgen.dimension import Dimension\n", + "from sequgen.parameter_space import ParameterSpace\n", + "\n", + "\n", + "MAXIMUM_FAILED_TRIES = 100\n", + "\n", + "\n", + "def peaks_overlap(peaks):\n", + " peaks = peaks_sort(peaks)\n", + " for i in range(0, len(peaks)-1):\n", + " if peaks[i]['location'] + peaks[i]['width'] >= peaks[i+1]['location']:\n", + " return(True)\n", + " return(False)\n", + "\n", + "\n", + "def peaks_sort(peaks):\n", + " return([ peak for peak in sorted(peaks, key=lambda p:p['location']) ])\n", "\n", - "channel_1 = constant(time_axis, 0)" + "\n", + "def peaks_generate(parameter_space, iterations):\n", + " peaks = []\n", + " failed_tries = 0\n", + " while len(peaks) < iterations and failed_tries < MAXIMUM_FAILED_TRIES:\n", + " new_peak = parameter_space.sample()\n", + " if peaks_overlap(peaks + [new_peak]):\n", + " failed_tries += 1\n", + " else:\n", + " peaks.append(new_peak)\n", + " peaks = peaks_sort(peaks)\n", + " failed_tries = 0\n", + " return peaks" ] }, { - "cell_type": "markdown", + "cell_type": "code", + "execution_count": 3, "metadata": {}, + "outputs": [], "source": [ - "Next, we define how many peaks we want, of what width and at what location" + "def make_bed_time():\n", + " parameter_space = ParameterSpace([\n", + " Dimension(\"location\", 60*22, 60*26),\n", + " Dimension(\"width\", 60*6, 60*9),\n", + " ])\n", + " bed_time = peaks_generate(parameter_space, 1)\n", + " return(bed_time)" ] }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 4, "metadata": {}, "outputs": [], "source": [ - "import random\n", - "from sequgen.dimension import Dimension\n", - "from sequgen.parameter_space import ParameterSpace\n", - "\n", - "def overlap(peaks):\n", - " peaks = [ peak for peak in sorted(peaks, key=lambda p:p['location']) ]\n", - " for i in range(0, len(peaks)-1):\n", - " if peaks[i]['location'] + peaks[i]['width'] >= peaks[i+1]['location']:\n", - " return(True)\n", - " return(False)\n", - "\n", - "iterations = random.randint(8,12)\n", - "peaks = []\n", - "start_time = time_axis[0]\n", - "while len(peaks) < iterations:\n", - " channel_1_parameter_space = ParameterSpace([\n", - " Dimension(\"location\", start_time, time_axis[-1]),\n", + "def make_pre_bed_time_rests(bed_time):\n", + " iterations_pre_bed_time = random.randint(0, 5)\n", + " parameter_space = ParameterSpace([\n", + " Dimension(\"location\", time_axis[0], bed_time[0][\"location\"]),\n", " Dimension(\"width\", 10, 30),\n", " ])\n", - " new_peak = channel_1_parameter_space.sample()\n", - " if not overlap(peaks+[new_peak]):\n", - " peaks.append(new_peak)" + " pre_bed_time_rests = peaks_generate(parameter_space, iterations_pre_bed_time)\n", + " return(pre_bed_time_rests)" ] }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "def make_bed_time_rests(bed_time):\n", + " iterations_bed_time = random.randint(0, 3)\n", + " parameter_space = ParameterSpace([\n", + " Dimension(\"location\", bed_time[0][\"location\"], bed_time[0][\"location\"]+bed_time[0][\"width\"]),\n", + " Dimension(\"width\", 60*2, 60*8),\n", + " ])\n", + " bed_time_rests = peaks_generate(parameter_space, iterations_bed_time)\n", + " return(bed_time_rests)" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "def make_post_bed_time_rests(bed_time):\n", + " iterations_post_bed_time = random.randint(0, 1)\n", + " parameter_space = ParameterSpace([\n", + " Dimension(\"location\", bed_time[0][\"location\"]+bed_time[0][\"width\"], time_axis[-1]),\n", + " Dimension(\"width\", 10, 30),\n", + " ])\n", + " post_bed_time_rests = peaks_generate(parameter_space, iterations_post_bed_time)\n", + " return(post_bed_time_rests)" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "def make_sleep_periods(pre_bed_time_rests, bed_time_rests, post_bed_time_rests):\n", + " sleep_periods = []\n", + " for rest in pre_bed_time_rests + bed_time_rests + post_bed_time_rests:\n", + " iterations = random.randint(0, 2)\n", + " parameter_space = ParameterSpace([\n", + " Dimension(\"location\", rest[\"location\"], rest[\"location\"]+rest[\"width\"]),\n", + " Dimension(\"width\", 0.5*rest[\"width\"], rest[\"width\"]),\n", + " ])\n", + " sleep_periods.extend(peaks_generate(parameter_space, iterations))\n", + " return(sleep_periods)" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "def make_signal():\n", + " bed_time = make_bed_time()\n", + " pre_bed_time_rests = make_pre_bed_time_rests(bed_time)\n", + " bed_time_rests = make_bed_time_rests(bed_time)\n", + " post_bed_time_rests = make_post_bed_time_rests(bed_time)\n", + " sleep_periods = make_sleep_periods(pre_bed_time_rests, bed_time_rests, post_bed_time_rests)\n", + " return(bed_time, pre_bed_time_rests, bed_time_rests, post_bed_time_rests, sleep_periods)" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "import matplotlib.pyplot as plt\n", + "from matplotlib.patches import StepPatch\n", + "\n", + "\n", + "def make_edges_and_values(periods, height=1):\n", + " values = []\n", + " edges = []\n", + " for period in periods:\n", + " edges.append(period['location'])\n", + " values.append(height)\n", + " edges.append(period['location']+period['width'])\n", + " values.append(0)\n", + " edges.append(edges[-1]+1)\n", + " return(edges, values)\n", + "\n", + "def plot(rest, sleep, bedtime):\n", + " fig, axs = plt.subplots(3, 1, figsize=(10,4))\n", + " edges, values = make_edges_and_values(sleep)\n", + " patch = StepPatch(values=values, edges=edges, color=\"C2\", label=\"sleep periods\")\n", + " axs[0].add_patch(patch)\n", + " axs[0].set_xlim(time_axis[0], time_axis[-1])\n", + " axs[0].set_ylim(0, 2)\n", + " axs[0].tick_params(left=False, labelleft=False)\n", + " axs[0].legend()\n", + " edges, values = make_edges_and_values(rest, height=-1)\n", + " patch = StepPatch(values=values, edges=edges, color=\"C8\", label=\"rest periods\")\n", + " axs[1].add_patch(patch)\n", + " axs[1].set_xlim(time_axis[0], time_axis[-1])\n", + " axs[1].set_ylim(-2, 0)\n", + " axs[1].tick_params(left=False, labelleft=False)\n", + " axs[1].legend()\n", + " edges, values = make_edges_and_values(bed_time)\n", + " patch = StepPatch(values=values, edges=edges, color=\"C7\", label=\"main bedtime\")\n", + " axs[2].add_patch(patch)\n", + " axs[2].set_xlim(time_axis[0], time_axis[-1])\n", + " axs[2].set_ylim(0, 2)\n", + " axs[2].tick_params(left=False, labelleft=False)\n", + " axs[2].legend()\n", + " plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Generate and plot" + ] + }, + { + "cell_type": "code", + "execution_count": 10, "metadata": {}, "outputs": [ { "data": { + "image/png": "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FP7D7MRTX+y27bX2gx/8gIsuuoiBAwd2+7Zra2u59957uf322zu8TlVVFbW1tQwZ4n/WlSRpb/nUZ3i6M+x0dnspJXbs2NGp7f/gBz/gT3/6U2e7tUfbt2+npqamU2FHkiT1jH3uktbGjRs57rjj+MY3vsHw4cN54403uOWWWzj55JMZOXIk1113HQAffvghZ511FqNGjWL48OEsWLCA22+/nU2bNjF58mQmT56827arqqq44oorGDFiBGPHjqW+vh6ALVu2cO6553LyySdz8skns3TpUgCuv/56LrzwQiZMmMCFF17I4sWLOfvsswF45513+MpXvsLIkSMZN24cL730EgCNjY1MnTqVYcOG8c1vfpOUUtH+SpKk7vGpL2mVwvr167nnnnsYN24cixYtYv369SxbtoyUEl/+8pd59tln2bJlC0ceeSSPPfYYAFu3bmXw4MF8//vf5+mnny56CWnw4MGsWrWKe++9l8suu4z//M//5NJLL2XOnDmceuqp/O53v2PatGmsXbsWgDVr1rBkyRIGDBjA4sWLm7dz3XXXMWbMGB555BGeeuopvvGNb7BixQpuuOEGTj31VK699loee+wx7rzzTgB+9atf7dZfSZLUPfbJwHP00Uczbtw4ABYtWsSiRYsYM2YMAB988AHr169n4sSJXH755cybN4+zzz6biRMndmjb559/fvPznDlzAHjyySdZs2ZN8zLvvfceH3zwAQBf/vKXGTBgwG7bWbJkCQ899BAAZ5xxBo2Njbz33ns8++yzPPzwwwCcddZZHHrooQCMGDGiS/2VJEl7tk8GngMPPLB5OqXEVVddxbe+9a3dllu+fDm/+MUvuOaaa5gyZQrXXnvtHrfd8u3fO6d37NjBCy+8QHl5ebt9+TSGDh3apf5KkqQ92+fu4Wlt2rRp3HXXXc1nXN58803eeustNm3axMCBA7nggguYO3cuy5cvB2DQoEG8//77Rbe3896ZBQsWMH78eACmTp3KD3/4w+ZlVqxYscd+TZw4kfvuuw+AxYsXM2TIEA4++GBOO+007r//fgB++ctf8u677wIU7a8kSfr0PvUZngMOGNLtb0vvjKlTp7J27drmcHLQQQfxk5/8hPr6eubOnUufPn0oKyvjxz/+MQAXXXQR06dP58gjj+Tpp5/ebXvvvvsuI0eOpH///syfPx+A22+/nb/9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\n", "text/plain": [ - "[{'location': 844.6832038089898, 'width': 28.86811004628262},\n", - " {'location': 1607.0707313223427, 'width': 27.832839252549945},\n", - " {'location': 1258.2611848841843, 'width': 17.969290975131415},\n", - " {'location': 1824.0410289912827, 'width': 25.339087800995205},\n", - " {'location': 1478.172539982449, 'width': 27.763902801091426},\n", - " {'location': 1674.2902318654558, 'width': 21.796208634427515},\n", - " {'location': 2138.1054655357575, 'width': 15.316048374888132},\n", - " {'location': 1073.2816828555506, 'width': 28.992778326933664},\n", - " {'location': 1281.2940788829344, 'width': 11.007700940398312},\n", - " {'location': 1428.6736924064255, 'width': 19.743754138923432}]" + "
" ] }, - "execution_count": 4, - "metadata": {}, - "output_type": "execute_result" + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" } ], "source": [ - "peaks" + "bed_time, pre_bed_time_rests, bed_time_rests, post_bed_time_rests, sleep_periods = make_signal()\n", + "plot(pre_bed_time_rests + bed_time_rests + post_bed_time_rests, sleep_periods, bed_time)" ] }, { From 55066d4f3530826fa9884b375a4713a443cd8f61 Mon Sep 17 00:00:00 2001 From: Erik Tjong Kim Sang Date: Tue, 6 Apr 2021 12:59:25 +0200 Subject: [PATCH 3/5] fixed boundaries & added export --- ggir-use-case-1.ipynb | 110 +++++++++++++++++++++++++++++++----------- 1 file changed, 81 insertions(+), 29 deletions(-) diff --git a/ggir-use-case-1.ipynb b/ggir-use-case-1.ipynb index 027a2e6..a18be9f 100644 --- a/ggir-use-case-1.ipynb +++ b/ggir-use-case-1.ipynb @@ -35,7 +35,7 @@ "source": [ "## 2. Channels\n", "\n", - "We define how many peaks we want, of what width and at what location" + "We define how many peaks we want, of what width and at what location. A challenge is that the width of the peak is not only bounded by the maximum value of width but also by the available time frame. A peak cannot extend beyond the available time frame because we want to be able to concatenate time series. We define the final point a the time frame in the parameter `maximum`." ] }, { @@ -64,12 +64,16 @@ " return([ peak for peak in sorted(peaks, key=lambda p:p['location']) ])\n", "\n", "\n", + "def peak_extends_maximum(peak):\n", + " return('maximum' in peak and peak['maximum'] < peak['location'] + peak['width']) \n", + "\n", + "\n", "def peaks_generate(parameter_space, iterations):\n", " peaks = []\n", " failed_tries = 0\n", " while len(peaks) < iterations and failed_tries < MAXIMUM_FAILED_TRIES:\n", " new_peak = parameter_space.sample()\n", - " if peaks_overlap(peaks + [new_peak]):\n", + " if peak_extends_maximum(new_peak) or peaks_overlap(peaks + [new_peak]):\n", " failed_tries += 1\n", " else:\n", " peaks.append(new_peak)\n", @@ -85,9 +89,12 @@ "outputs": [], "source": [ "def make_bed_time():\n", + " minimum = 60*22\n", + " maximum = 60*26\n", " parameter_space = ParameterSpace([\n", - " Dimension(\"location\", 60*22, 60*26),\n", + " Dimension(\"location\", minimum, maximum),\n", " Dimension(\"width\", 60*6, 60*9),\n", + " Dimension(\"maximum\", maximum + 60*9),\n", " ])\n", " bed_time = peaks_generate(parameter_space, 1)\n", " return(bed_time)" @@ -101,9 +108,12 @@ "source": [ "def make_pre_bed_time_rests(bed_time):\n", " iterations_pre_bed_time = random.randint(0, 5)\n", + " minimum = time_axis[0]\n", + " maximum = bed_time[0][\"location\"]\n", " parameter_space = ParameterSpace([\n", - " Dimension(\"location\", time_axis[0], bed_time[0][\"location\"]),\n", + " Dimension(\"location\", minimum, maximum),\n", " Dimension(\"width\", 10, 30),\n", + " Dimension(\"maximum\", maximum),\n", " ])\n", " pre_bed_time_rests = peaks_generate(parameter_space, iterations_pre_bed_time)\n", " return(pre_bed_time_rests)" @@ -117,9 +127,12 @@ "source": [ "def make_bed_time_rests(bed_time):\n", " iterations_bed_time = random.randint(0, 3)\n", + " minimum = bed_time[0][\"location\"]\n", + " maximum = bed_time[0][\"location\"] + bed_time[0][\"width\"]\n", " parameter_space = ParameterSpace([\n", - " Dimension(\"location\", bed_time[0][\"location\"], bed_time[0][\"location\"]+bed_time[0][\"width\"]),\n", + " Dimension(\"location\", minimum, maximum),\n", " Dimension(\"width\", 60*2, 60*8),\n", + " Dimension(\"maximum\", maximum)\n", " ])\n", " bed_time_rests = peaks_generate(parameter_space, iterations_bed_time)\n", " return(bed_time_rests)" @@ -133,9 +146,12 @@ "source": [ "def make_post_bed_time_rests(bed_time):\n", " iterations_post_bed_time = random.randint(0, 1)\n", + " minimum = bed_time[0][\"location\"] + bed_time[0][\"width\"]\n", + " maximum = time_axis[-1]\n", " parameter_space = ParameterSpace([\n", - " Dimension(\"location\", bed_time[0][\"location\"]+bed_time[0][\"width\"], time_axis[-1]),\n", + " Dimension(\"location\", minimum, maximum),\n", " Dimension(\"width\", 10, 30),\n", + " Dimension(\"maximum\", maximum),\n", " ])\n", " post_bed_time_rests = peaks_generate(parameter_space, iterations_post_bed_time)\n", " return(post_bed_time_rests)" @@ -151,9 +167,12 @@ " sleep_periods = []\n", " for rest in pre_bed_time_rests + bed_time_rests + post_bed_time_rests:\n", " iterations = random.randint(0, 2)\n", + " minimum = rest[\"location\"]\n", + " maximum = rest[\"location\"] + rest[\"width\"]\n", " parameter_space = ParameterSpace([\n", - " Dimension(\"location\", rest[\"location\"], rest[\"location\"]+rest[\"width\"]),\n", + " Dimension(\"location\", minimum, maximum),\n", " Dimension(\"width\", 0.5*rest[\"width\"], rest[\"width\"]),\n", + " Dimension(\"maximum\", maximum),\n", " ])\n", " sleep_periods.extend(peaks_generate(parameter_space, iterations))\n", " return(sleep_periods)" @@ -195,29 +214,22 @@ " edges.append(edges[-1]+1)\n", " return(edges, values)\n", "\n", + "\n", + "def plot_draw_graph(ax, data, color, label, height=1):\n", + " edges, values = make_edges_and_values(data, height=height)\n", + " patch = StepPatch(values=values, edges=edges, color=color, label=label)\n", + " ax.add_patch(patch)\n", + " ax.set_xlim(time_axis[0], time_axis[-1])\n", + " ax.set_ylim(min(0, 2*height), max(0, 2*height))\n", + " ax.tick_params(left=False, labelleft=False)\n", + " ax.legend()\n", + "\n", + " \n", "def plot(rest, sleep, bedtime):\n", " fig, axs = plt.subplots(3, 1, figsize=(10,4))\n", - " edges, values = make_edges_and_values(sleep)\n", - " patch = StepPatch(values=values, edges=edges, color=\"C2\", label=\"sleep periods\")\n", - " axs[0].add_patch(patch)\n", - " axs[0].set_xlim(time_axis[0], time_axis[-1])\n", - " axs[0].set_ylim(0, 2)\n", - " axs[0].tick_params(left=False, labelleft=False)\n", - " axs[0].legend()\n", - " edges, values = make_edges_and_values(rest, height=-1)\n", - " patch = StepPatch(values=values, edges=edges, color=\"C8\", label=\"rest periods\")\n", - " axs[1].add_patch(patch)\n", - " axs[1].set_xlim(time_axis[0], time_axis[-1])\n", - " axs[1].set_ylim(-2, 0)\n", - " axs[1].tick_params(left=False, labelleft=False)\n", - " axs[1].legend()\n", - " edges, values = make_edges_and_values(bed_time)\n", - " patch = StepPatch(values=values, edges=edges, color=\"C7\", label=\"main bedtime\")\n", - " axs[2].add_patch(patch)\n", - " axs[2].set_xlim(time_axis[0], time_axis[-1])\n", - " axs[2].set_ylim(0, 2)\n", - " axs[2].tick_params(left=False, labelleft=False)\n", - " axs[2].legend()\n", + " plot_draw_graph(axs[0], sleep, \"C2\", \"sleep periods\")\n", + " plot_draw_graph(axs[1], rest, \"C8\", \"rest periods\", height=-1)\n", + " plot_draw_graph(axs[2], bed_time, \"C7\", \"main bed time\")\n", " plt.show()" ] }, @@ -235,7 +247,7 @@ "outputs": [ { "data": { - "image/png": "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FP7D7MRTX+y27bX2gx/8gIsuuoiBAwd2+7Zra2u59957uf322zu8TlVVFbW1tQwZ4n/WlSRpb/nUZ3i6M+x0dnspJXbs2NGp7f/gBz/gT3/6U2e7tUfbt2+npqamU2FHkiT1jH3uktbGjRs57rjj+MY3vsHw4cN54403uOWWWzj55JMZOXIk1113HQAffvghZ511FqNGjWL48OEsWLCA22+/nU2bNjF58mQmT56827arqqq44oorGDFiBGPHjqW+vh6ALVu2cO6553LyySdz8skns3TpUgCuv/56LrzwQiZMmMCFF17I4sWLOfvsswF45513+MpXvsLIkSMZN24cL730EgCNjY1MnTqVYcOG8c1vfpOUUtH+SpKk7vGpL2mVwvr167nnnnsYN24cixYtYv369SxbtoyUEl/+8pd59tln2bJlC0ceeSSPPfYYAFu3bmXw4MF8//vf5+mnny56CWnw4MGsWrWKe++9l8suu4z//M//5NJLL2XOnDmceuqp/O53v2PatGmsXbsWgDVr1rBkyRIGDBjA4sWLm7dz3XXXMWbMGB555BGeeuopvvGNb7BixQpuuOEGTj31VK699loee+wx7rzzTgB+9atf7dZfSZLUPfbJwHP00Uczbtw4ABYtWsSiRYsYM2YMAB988AHr169n4sSJXH755cybN4+zzz6biRMndmjb559/fvPznDlzAHjyySdZs2ZN8zLvvfceH3zwAQBf/vKXGTBgwG7bWbJkCQ899BAAZ5xxBo2Njbz33ns8++yzPPzwwwCcddZZHHrooQCMGDGiS/2VJEl7tk8GngMPPLB5OqXEVVddxbe+9a3dllu+fDm/+MUvuOaaa5gyZQrXXnvtHrfd8u3fO6d37NjBCy+8QHl5ebt9+TSGDh3apf5KkqQ92+fu4Wlt2rRp3HXXXc1nXN58803eeustNm3axMCBA7nggguYO3cuy5cvB2DQoEG8//77Rbe3896ZBQsWMH78eACmTp3KD3/4w+ZlVqxYscd+TZw4kfvuuw+AxYsXM2TIEA4++GBOO+007r//fgB++ctf8u677wIU7a8kSfr0PvUZngMOGNLtb0vvjKlTp7J27drmcHLQQQfxk5/8hPr6eubOnUufPn0oKyvjxz/+MQAXXXQR06dP58gjj+Tpp5/ebXvvvvsuI0eOpH///syfPx+A22+/nb/9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\n", + "image/png": "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knKv3dfw7Ok3i07no4/e6Yy+AIX/xjr+jBc7bXt7+v73v88VV1xBnz59On3b1dXVzJ07l7vuuqvN61RUVFBdXc2AAQf3f6GVJKk72+8jPJ0Zdtq7vZQSu3btatf2v//97/PnP/+5vd3ap507d1JVVdWusCNJkrrGQXdKa8OGDXzuc5/ja1/7GkOHDuXNN99kzpw5jBo1ilNOOYWbbroJgO3bt3PeeecxfPhwhg4dyvz587nrrrvYuHEjEydOZOLEiXttu6KigmuvvZZhw4YxevRoamtrAdi8eTMXXXQRo0aNYtSoUSxevBiAm2++mcsuu4xx48Zx2WWXsXDhQs4//3wAtmzZwgUXXMApp5zCmDFjePnllwGor69n8uTJDBkyhK9//euklFrsryRJ6hz7fUqrGNatW8cDDzzAmDFjWLBgAevWrWPp0qWklPjSl77ECy+8wObNmxk0aBBPPvkkAFu3bqV///7ceeedPPfccy2eQurfvz8rV65k7ty5XH311fznf/4nV111FTNmzOCMM87gD3/4A+eeey5r1qwBYPXq1SxatIjDDz+chQsXNm7npptuYuTIkTzxxBM8++yzfO1rX2P58uXccsstnHHGGcyePZsnn3ySe++9F4Bf//rXe/VXkiR1joMy8Bx//PGMGTMGgAULFrBgwQJGjhwJwLZt21i3bh3jx4/nmmuuYdasWZx//vmMHz++Tdu+5JJLGu9nzJgBwDPPPMPq1asbl3n//ffZtm0bAF/60pc4/PDD99rOokWLeOyxxwA4++yzqa+v5/333+eFF17g8ccfB+C8887j6KOPBmDYsGEd6q8kSdq3gzLw9O3bt3E6pcT111/PN77xjb2WW7ZsGb/85S+58cYbmTRpErNnz97ntpt+/PuT6V27drFkyRJKS0tb7cv+GDx4cIf6K0mS9u2gu4ZnT+eeey733Xdf4xGXt956i7fffpuNGzfSp08fLr30UmbOnMmyZcsA6NevHx988EGL2/vk2pn58+czduxYACZPnswPfvCDxmWWL1++z36NHz+eBx98EICFCxcyYMAAjjzySM4880weeughAH71q1/x7rvvArTYX0mStP/2+wjPYYcN6PSPpbfH5MmTWbNmTWM4OeKII/jJT35CbW0tM2fOpEePHpSUlPDjH/8YgCuuuIIpU6YwaNAgnnvuub229+6773LKKafQu3dv5s2bB8Bdd93F3//933PKKaewc+dOzjzzTO65555W+3XzzTczffp0TjnlFPr06cMDDzwAFK7tueSSSxgyZAhf+MIX+Ou//msAVq5c2Wx/JUnS/otPPiXUnKqqqlRdXb1b25o1azjppJMOdL+Kort/J06eay9J0v6KiJqUUlVz8w76U1qSJEn7clBetHygbNiwodhdkCRJB0CHjvC0dhpMB4Y1lySp49odeEpLS6mvr3cH3IVSStTX1zf7sXhJkrRv7T6lVV5eTl1dHZs3bz4Q/VELSktLKS8vL3Y3JEk6KLU78JSUlFBZWXkg+iJJknRA+CktSZKUewYeSZKUewYeSZKUe61+03JEbAbe6Lru7GYA0Hn/s+LQYd3az5p1jHVrP2vWMdat/Q7Vmh2fUjqmuRmtBp5iiojqlr4eWi2zbu1nzTrGurWfNesY69Z+1mxvntKSJEm5Z+CRJEm5150Dz78VuwMHKevWftasY6xb+1mzjrFu7WfN9tBtr+GRJEnqLN35CI8kSVKnMPBIkqTcK1rgiYgZEfFKRKyKiHkRURoRlRHxYkTURsT8iDgsW7Z39rg2m19RrH53tYi4LyLejohVTdo+FRFPR8S67P7orD0i4q6sTi9HxKlN1rk8W35dRFxejNfSlVqo25yIWJvV5mcRcVSTeddndXs1Is5t0j4la6uNiOu6+GV0qeZq1mTeNRGRImJA9tixlmmpbhHxrWy8vRIR32vS7lhr/udzREQsiYjlEVEdEaOzdscaEBHHRcRzEbE6G1NXZe3uD9oqpdTlN+AzwOvA4dnjnwLTsvuvZG33AFdm098E7smmvwLML0a/i1SrM4FTgVVN2r4HXJdNXwd8N5v+IvArIIAxwItZ+6eA32f3R2fTRxf7tRWhbpOBXtn0d5vU7WRgBdAbqATWAz2z23rgBOCwbJmTi/3aurJmWftxwFMUvoR0gGOtTWNtIvAM0Dt7fKxjbZ81WwD8TZPxtdCxtlvNBgKnZtP9gNey8eT+oI23Yp7S6gUcHhG9gD7AJuBs4NFs/gPABdn01Owx2fxJERFd19XiSSm9AGzZo7lpPfas09xUsAQ4KiIGAucCT6eUtqSU3gWeBqYc8M4XUXN1SyktSCntzB4uAcqz6anAwymlD1NKrwO1wOjsVptS+n1K6SPg4WzZXGphrAH8C3At0PQTDo61TAt1uxK4PaX0YbbM21m7Y40Wa5aAI7Pp/sDGbNqxBqSUNqWUlmXTHwBrKBw8cH/QRkUJPCmlt4A7gD9QCDpbgRrgvSY7pDoKbybZ/ZvZujuz5cu6ss/dzKdTSpuy6T8Cn86mG+uU+aSGLbUfyqZT+OsHrFuLImIq8FZKacUes6xZ6wYD47NT8M9HxKis3bq17GpgTkS8SWH/cH3Wbs32kF3WMRJ4EfcHbVaUwJOdY5xK4ZDuIKAvh0jC7GypcIzS7xZoh4i4AdgJPFjsvnRnEdEH+A4wu9h9OQj1onDKYAwwE/jpoXJUej9cCcxIKR0HzADuLXJ/uqWIOAJ4DLg6pfR+03nuD1rX6vfwDBgwIFVUVHRdbyRJkjqopqbmndTCPw/t1dqKFRUVVFdXH5heSZIkdaKIeKOleX4PjyRJyj0DjyRJyj0DjyRJyr1Wr+GRJOlQ0dDQQF1dHTt27Ch2V7QPpaWllJeXU1JS0uZ1DDySJAF1dXX069ePiooK/BaB7iulRH19PXV1dVRWVrZ5PU9pSZIE7Nixg7KyMsNONxcRlJWVtftInIFHkqSMYefg0JH3ycAjSZJyz2t4JElqxpw5c9i+fXunba9v377MnDmz07a3p+rqaubOnctdd93V5nWOOOIItm3b1uHnbG799957j4ceeohvfvObAGzcuJFvf/vbPProo81tost4hEeSpGZ0Ztg5ENvbU1VVVbvCzoHy3nvv8aMf/ajx8aBBg4oedsDAI0lSt7BhwwY+//nPM23aNAYPHsxXv/pVnnnmGcaNG8eJJ57I0qVLAVi6dCljx45l5MiRfOELX+DVV18FYOHChZx//vkA3HzzzUyfPp0JEyZwwgkntBqEZsyYwZAhQ5g0aRKbN28GYP369UyZMoXTTjuN8ePHs3btWgBef/11xo4dy7Bhw7jxxhub3d51113H+vXrGTFiBDNnzmTDhg0MHToUgPvvv58LLriAc845h4qKCn74wx9y5513MnLkSMaMGcOWLVtaff79YeCRJKmbqK2t5ZprrmHt2rWsXbuWhx56iEWLFnHHHXfwT//0TwB8/vOf5ze/+Q2/+93vuPXWW/nOd77T7LbWrl3LU089xdKlS7nllltoaGjYa5nt27dTVVXFK6+8wllnncUtt9wCwBVXXMEPfvADampquOOOOxpPT1111VVceeWVrFy5koEDBzb7vLfffjuf/exnWb58OXPmzNlr/qpVq3j88cd56aWXuOGGG+jTpw+/+93vGDt2LHPnzm31+feH1/BIktRNVFZWMmzYMIDGoy4RwbBhw9iwYQMAW7du5fLLL2fdunVERLNBBuC8886jd+/e9O7dm2OPPZY//elPlJeX77ZMjx49uPjiiwG49NJLufDCC9m2bRv//d//zZe//OXG5T788EMAFi9ezGOPPQbAZZddxqxZs9r9GidOnEi/fv3o168f/fv352//9m8BGDZsGC+//HKrz78/DDySJHUTvXv3bpzu0aNH4+MePXqwc+dOAP7xH/+RiRMn8rOf/YwNGzYwYcKEfW6rZ8+ejeu3JiLYtWsXRx11FMuXL29xmf2xr9e4r+fvKE9pSZJ0ENm6dSuf+cxngMI1Mftj165djRcUP/TQQ5xxxhkceeSRVFZW8sgjjwCFbzZesWIFAOPGjePhhx8G4MEHH2x2m/369eODDz7ocJ9ae/79YeCRJKkZffv27Zbbu/baa7n++usZOXJkm47a7KtPS5cuZejQoTz77LPMnj0bKISZe++9l+HDhzNkyBB+/vOfA/Cv//qv3H333QwbNoy33nqr2W2WlZUxbtw4hg4d2uGP4bf0/PsjUkotzqyqqkrV1dX7/SSSJHV3a9as4aSTTip2N9RGzb1fEVGTUqpqbnmP8EiSpNwz8EiSpNwz8EiSlGntMg91Hx15nww8kiQBpaWl1NfXG3q6uZQS9fX1lJaWtms9v4dHkiSgvLycurq6xn+voO6rtLR0ry9R3BcDjyRJQElJCZWVlcXuhg4QT2lJkqTcM/BIkqTcM/BIkqTcM/BIkqTcM/BIkqTcM/BIkqTcM/BIkqTc83t4JBXNnDlz2L59e7G7IXVLffv2ZebMmcXuRm54hEdS0Rh2pJb589G5DDySJCn3DDySJCn3DDySJCn3DDySJCn3DDySJCn3DDySJCn3DDySJCn3DDySJCn3DDySJCn3DDySJCn3DDySJCn3DDySJCn3DDySJCn3DDySJCn3DDySJCn3DDySJCn3DDySJCn3DDySJCn3DDySJCn3DDySJCn3DDySJCn3DDySJCn3DDySJCn3DDySJCn3DDySJCn3DDySJCn3DDySJCn3DDySJCn3DDySJCn3DDySJCn3IqXU8syIzcAbXded3QwA3inScx/MrFv7WbOOsW7tZ806xrq136Fas+NTSsc0N6PVwFNMEVGdUqoqdj8ONtat/axZx1i39rNmHWPd2s+a7c1TWpIkKfcMPJIkKfe6c+D5t2J34CBl3drPmnWMdWs/a9Yx1q39rNkeuu01PJIkSZ2lOx/hkSRJ6hQGHkmSlHtFCzwRMSMiXomIVRExLyJKI6IyIl6MiNqImB8Rh2XL9s4e12bzK4rV764WEfdFxNsRsapJ26ci4umIWJfdH521R0TcldXp5Yg4tck6l2fLr4uIy4vxWrpSC3WbExFrs9r8LCKOajLv+qxur0bEuU3ap2RttRFxXRe/jC7VXM2azLsmIlJEDMgeO9YyLdUtIr6VjbdXIuJ7Tdoda83/fI6IiCURsTwiqiNidNbuWAMi4riIeC4iVmdj6qqs3f1BW6WUuvwGfAZ4HTg8e/xTYFp2/5Ws7R7gymz6m8A92fRXgPnF6HeRanUmcCqwqknb94DrsunrgO9m018EfgUEMAZ4MWv/FPD77P7obProYr+2ItRtMtArm/5uk7qdDKwAegOVwHqgZ3ZbD5wAHJYtc3KxX1tX1ixrPw54isKXkA5wrLVprE0EngF6Z4+Pdazts2YLgL9pMr4WOtZ2q9lA4NRsuh/wWjae3B+08VbMU1q9gMMjohfQB9gEnA08ms1/ALggm56aPSabPykiouu6WjwppReALXs0N63HnnWamwqWAEdFxEDgXODplNKWlNK7wNPAlAPe+SJqrm4ppQUppZ3ZwyVAeTY9FXg4pfRhSul1oBYYnd1qU0q/Tyl9BDycLZtLLYw1gH8BrgWafsLBsZZpoW5XArenlD7Mlnk7a3es0WLNEnBkNt0f2JhNO9aAlNKmlNKybPoDYA2FgwfuD9qoKIEnpfQWcAfwBwpBZytQA7zXZIdUR+HNJLt/M1t3Z7Z8WVf2uZv5dEppUzb9R+DT2XRjnTKf1LCl9kPZdAp//YB1a1FETAXeSimt2GOWNWvdYGB8dgr++YgYlbVbt5ZdDcyJiDcp7B+uz9qt2R6yyzpGAi/i/qDNihJ4snOMUykc0h0E9OUQSZidLRWOUfrdAu0QETcAO4EHi92X7iwi+gDfAWYXuy8HoV4UThmMAWYCPz1UjkrvhyuBGSml44AZwL1F7k+3FBFHAI8BV6eU3m86z/1B64p1Sut/Aa+nlDanlBqAx4FxFA659cqWKQfeyqbfonAdAdn8/kB913a5W/lTdmiS7P6Tw+WNdcp8UsOW2g85ETENOB/4avbLAaxbSz5L4Y+SFRGxgcLrXxYRf4U125c64PHsdMJSYBeFf+Zo3Vp2OYV9AcAjFE7zgTVrFBElFMLOgymlT2rl/qCNihV4/gCMiYg+2V89k4DVwHPA/86WuRz4eTb9i+wx2fxnm+ysDkVN67Fnnb6WXZ0/BtiaHep8CpgcEUdnR9cmZ22HlIiYQuFalC+llP7cZNYvgK9E4dOAlcCJwFLgJeDEKHx68DAKF8z/oqv7XSwppZUppWNTShUppQoKO/FTU0p/xLG2L09QuHCZiBhM4ULkd3CstWYjcFY2fTawLpt2rFH41BWFo15rUkp3Npnl/qCtinW1NHALsBZYBfw/Cp9aOIHCD38thYT/ySccSrPHtdn8E4rV7yLUaR6F65waKOxw/i+F65f+i8IvhGeAT2XLBnA3hU97rASqmmxnela/WuD/FPt1FalutRTOXS/Pbvc0Wf6GrG6vkn1SJGv/IoVPQ6wHbij26+rqmu0xfwP/8yktx1rrY+0w4CfZ77dlwNmOtX3W7AwK13KuoHBtymmOtd1qdgaF01UvN/kd9kX3B22/+a8lJElS7vlNy5IkKfcMPJIkKfcMPJIkKfcMPJIkKfcMPJIkKfcMPJIkKfcMPJIkKff+P0tL9AoxQX2SAAAAAElFTkSuQmCC\n", "text/plain": [ "
" ] @@ -251,6 +263,46 @@ "plot(pre_bed_time_rests + bed_time_rests + post_bed_time_rests, sleep_periods, bed_time)" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Export" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Rest starts: 844 1043 1451 1756 2042 \n", + "Rest ends: 871 1072 1688 1882 2054 \n", + "Sleep starts: 1054 1509 1760 \n", + "Sleep ends: 1071 1630 1831 \n", + "Bed time starts: 1445 \n", + "Bed time ends: 1961 \n" + ] + } + ], + "source": [ + "def print_data(data, data_name):\n", + " print(data_name+ \" starts:\", end=\" \")\n", + " for peak in data:\n", + " print(round(peak['location']), end=\" \")\n", + " print(\"\\n\" + data_name + \" ends:\", end=\" \")\n", + " for peak in data:\n", + " print(round(peak['location'] + peak['width']), end=\" \")\n", + " print()\n", + " \n", + "print_data(pre_bed_time_rests + bed_time_rests + post_bed_time_rests, \"Rest\")\n", + "print_data(sleep_periods, \"Sleep\")\n", + "print_data(bed_time, \"Bed time\")" + ] + }, { "cell_type": "code", "execution_count": null, From f0effcc217bae33aacf0b0c45bf55a07e657c3dd Mon Sep 17 00:00:00 2001 From: Erik Tjong Kim Sang Date: Tue, 6 Apr 2021 21:03:36 +0200 Subject: [PATCH 4/5] removed sleep periods --- ggir-use-case-1.ipynb | 284 ++++++++++++++++++++---------------------- 1 file changed, 133 insertions(+), 151 deletions(-) diff --git a/ggir-use-case-1.ipynb b/ggir-use-case-1.ipynb index a18be9f..9b0675a 100644 --- a/ggir-use-case-1.ipynb +++ b/ggir-use-case-1.ipynb @@ -6,16 +6,16 @@ "source": [ "# GGIR use case 1\n", "\n", - "This use case requires the generation of three signals: rest, sleep and main bed period. All signals appear in a time signal between 12:00 noon and 12:00 next day. Each signal consists of two binary signals: period starts and period ends. For reference, there is a larger [description of this use case](https://github.com/sequgen/sequgen/issues/21) as well as a [visualization](https://cran.r-project.org/web/packages/GGIR/vignettes/GGIR.html#42_Output_part_4) of the time signals (click on the tab `4.2.3 visualisation_sleep.pdf`)." + "This use case requires the generation of two types of related sleep signals: rest and main bed period. Both signals appear in a time signal between 12:00 noon and 12:00 next day. Each signal consists of two binary signals: period starts and period ends. For reference, there is a larger [description of this use case](https://github.com/sequgen/sequgen/issues/21) as well as a [visualization](https://cran.r-project.org/web/packages/GGIR/vignettes/GGIR.html#42_Output_part_4) of the time signals (click on the tab `4.2.3 visualisation_sleep.pdf`)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "## 1. Time axis\n", + "## 1. Peak generation\n", "\n", - "We model the time axis as a discrete list of minutes starting at 12\\*60 and ending at 36\\*60" + "The required time signals consist a series of peaks which can be generated with the sequgen functions. Let's start with importing the required functions." ] }, { @@ -24,18 +24,18 @@ "metadata": {}, "outputs": [], "source": [ - "import numpy as np\n", - "\n", - "time_axis = np.arange(12*60, 36*60+1)" + "import random\n", + "from sequgen.dimension import Dimension\n", + "from sequgen.parameter_space import ParameterSpace" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "## 2. Channels\n", + "sequgen only provides signals with a single peak, so we need to create our own function for generating signals with several peaks. Furthermore, the peaks need to satisfy two requirements: 1. peaks can not overlap each other, and 2. peaks cannot extend beyond the end of the available time frame. We need functions to check these constraints as well.\n", "\n", - "We define how many peaks we want, of what width and at what location. A challenge is that the width of the peak is not only bounded by the maximum value of width but also by the available time frame. A peak cannot extend beyond the available time frame because we want to be able to concatenate time series. We define the final point a the time frame in the parameter `maximum`." + "If a peak does not satisfy a constraint, it will be discarded and another peak will be generated. However, it is possible that there is no more room in the time frame for another peak that satifies the required constraints. To avoid entering an infinitive loop, we will only allow for 100 successive failed peak generation attempts." ] }, { @@ -44,11 +44,6 @@ "metadata": {}, "outputs": [], "source": [ - "import random\n", - "from sequgen.dimension import Dimension\n", - "from sequgen.parameter_space import ParameterSpace\n", - "\n", - "\n", "MAXIMUM_FAILED_TRIES = 100\n", "\n", "\n", @@ -68,9 +63,10 @@ " return('maximum' in peak and peak['maximum'] < peak['location'] + peak['width']) \n", "\n", "\n", - "def peaks_generate(parameter_space, iterations):\n", + "def peaks_generate(parameter_space):\n", " peaks = []\n", " failed_tries = 0\n", + " iterations = parameter_space.sample()[\"iterations\"]\n", " while len(peaks) < iterations and failed_tries < MAXIMUM_FAILED_TRIES:\n", " new_peak = parameter_space.sample()\n", " if peak_extends_maximum(new_peak) or peaks_overlap(peaks + [new_peak]):\n", @@ -82,154 +78,128 @@ " return peaks" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 2. Signal functions\n", + "\n", + "A signal consists of two main parts: main bed time, the time at night that a person is in bed, and resting times, several periods during the day when a person is resting. The function has six parameters: start and end point of the available start frame, minimum and maximum start of bed time and minimum and maximum length of the bed time period. The resting times are divided in three groups: pre-bed time rests, bed time rests and post-bed time rests." + ] + }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ - "def make_bed_time():\n", - " minimum = 60*22\n", - " maximum = 60*26\n", - " parameter_space = ParameterSpace([\n", - " Dimension(\"location\", minimum, maximum),\n", - " Dimension(\"width\", 60*6, 60*9),\n", - " Dimension(\"maximum\", maximum + 60*9),\n", - " ])\n", - " bed_time = peaks_generate(parameter_space, 1)\n", - " return(bed_time)" + "def make_signal(start_time, end_time, \n", + " bed_time_start_minimum, bed_time_start_maximum, \n", + " bed_time_minimum, bed_time_maximum,\n", + " bed_time_iterations_minimum, bed_time_iterations_maximum,\n", + " pre_bed_time_iterations_minimum, pre_bed_time_iterations_maximum,\n", + " post_bed_time_iterations_minimum, post_bed_time_iterations_maximum,\n", + " bed_time_rest_minimum, bed_time_rest_maximum,\n", + " other_rest_minimum, other_rest_maximum):\n", + " bed_time = make_bed_time(bed_time_start_minimum, bed_time_start_maximum, bed_time_minimum, bed_time_maximum)\n", + " pre_bed_time_rests = make_rests(start_time * 60, bed_time[0]['location'], \n", + " other_rest_minimum * 60, other_rest_maximum * 60, \n", + " pre_bed_time_iterations_minimum, pre_bed_time_iterations_maximum)\n", + " bed_time_rests = make_rests(bed_time[0]['location'], bed_time[0]['location']+bed_time[0]['width'],\n", + " bed_time_rest_minimum * 60, bed_time_rest_maximum * 60,\n", + " bed_time_iterations_minimum, bed_time_iterations_maximum)\n", + " post_bed_time_rests = make_rests(bed_time[0]['location']+bed_time[0]['width'], end_time*60,\n", + " other_rest_minimum * 60, other_rest_maximum * 60,\n", + " post_bed_time_iterations_minimum, post_bed_time_iterations_maximum)\n", + " return(bed_time, (pre_bed_time_rests + bed_time_rests + post_bed_time_rests))" ] }, { - "cell_type": "code", - "execution_count": 4, + "cell_type": "markdown", "metadata": {}, - "outputs": [], "source": [ - "def make_pre_bed_time_rests(bed_time):\n", - " iterations_pre_bed_time = random.randint(0, 5)\n", - " minimum = time_axis[0]\n", - " maximum = bed_time[0][\"location\"]\n", - " parameter_space = ParameterSpace([\n", - " Dimension(\"location\", minimum, maximum),\n", - " Dimension(\"width\", 10, 30),\n", - " Dimension(\"maximum\", maximum),\n", - " ])\n", - " pre_bed_time_rests = peaks_generate(parameter_space, iterations_pre_bed_time)\n", - " return(pre_bed_time_rests)" + "We create a function for generating an arbitrary bed time period that satisfies the constraints" ] }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 4, "metadata": {}, "outputs": [], "source": [ - "def make_bed_time_rests(bed_time):\n", - " iterations_bed_time = random.randint(0, 3)\n", - " minimum = bed_time[0][\"location\"]\n", - " maximum = bed_time[0][\"location\"] + bed_time[0][\"width\"]\n", + "def make_bed_time(bed_time_start_minimum, bed_time_start_maximum, bed_time_minimum, bed_time_maximum, maximum=None, iterations=1):\n", + " if maximum == None:\n", + " maximum = bed_time_start_maximum + bed_time_maximum\n", " parameter_space = ParameterSpace([\n", - " Dimension(\"location\", minimum, maximum),\n", - " Dimension(\"width\", 60*2, 60*8),\n", - " Dimension(\"maximum\", maximum)\n", + " Dimension(\"location\", bed_time_start_minimum * 60, bed_time_start_maximum * 60),\n", + " Dimension(\"width\", bed_time_minimum * 60, bed_time_maximum * 60),\n", + " Dimension(\"maximum\", maximum * 60),\n", + " Dimension(\"iterations\", iterations),\n", " ])\n", - " bed_time_rests = peaks_generate(parameter_space, iterations_bed_time)\n", - " return(bed_time_rests)" + " bed_time = peaks_generate(parameter_space)\n", + " return(bed_time)" ] }, { - "cell_type": "code", - "execution_count": 6, + "cell_type": "markdown", "metadata": {}, - "outputs": [], "source": [ - "def make_post_bed_time_rests(bed_time):\n", - " iterations_post_bed_time = random.randint(0, 1)\n", - " minimum = bed_time[0][\"location\"] + bed_time[0][\"width\"]\n", - " maximum = time_axis[-1]\n", - " parameter_space = ParameterSpace([\n", - " Dimension(\"location\", minimum, maximum),\n", - " Dimension(\"width\", 10, 30),\n", - " Dimension(\"maximum\", maximum),\n", - " ])\n", - " post_bed_time_rests = peaks_generate(parameter_space, iterations_post_bed_time)\n", - " return(post_bed_time_rests)" + "Next, we define a function for generating the rest times:" ] }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 5, "metadata": {}, "outputs": [], "source": [ - "def make_sleep_periods(pre_bed_time_rests, bed_time_rests, post_bed_time_rests):\n", - " sleep_periods = []\n", - " for rest in pre_bed_time_rests + bed_time_rests + post_bed_time_rests:\n", - " iterations = random.randint(0, 2)\n", - " minimum = rest[\"location\"]\n", - " maximum = rest[\"location\"] + rest[\"width\"]\n", - " parameter_space = ParameterSpace([\n", - " Dimension(\"location\", minimum, maximum),\n", - " Dimension(\"width\", 0.5*rest[\"width\"], rest[\"width\"]),\n", - " Dimension(\"maximum\", maximum),\n", - " ])\n", - " sleep_periods.extend(peaks_generate(parameter_space, iterations))\n", - " return(sleep_periods)" + "def make_rests(start_time, end_time, width_minimum, width_maximum, iterations_minimum, iterations_maximum):\n", + " parameter_space = ParameterSpace([\n", + " Dimension(\"location\", start_time, end_time),\n", + " Dimension(\"width\", width_minimum, width_maximum),\n", + " Dimension(\"maximum\", end_time),\n", + " Dimension(\"iterations\", iterations_minimum, iterations_maximum),\n", + " ])\n", + " rests = peaks_generate(parameter_space)\n", + " return(rests)" ] }, { - "cell_type": "code", - "execution_count": 8, + "cell_type": "markdown", "metadata": {}, - "outputs": [], "source": [ - "def make_signal():\n", - " bed_time = make_bed_time()\n", - " pre_bed_time_rests = make_pre_bed_time_rests(bed_time)\n", - " bed_time_rests = make_bed_time_rests(bed_time)\n", - " post_bed_time_rests = make_post_bed_time_rests(bed_time)\n", - " sleep_periods = make_sleep_periods(pre_bed_time_rests, bed_time_rests, post_bed_time_rests)\n", - " return(bed_time, pre_bed_time_rests, bed_time_rests, post_bed_time_rests, sleep_periods)" + "## 3. Plotting functions\n", + "\n", + "We use these functions for plotting the time series." ] }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "import matplotlib.pyplot as plt\n", - "from matplotlib.patches import StepPatch\n", - "\n", - "\n", - "def make_edges_and_values(periods, height=1):\n", - " values = []\n", - " edges = []\n", - " for period in periods:\n", - " edges.append(period['location'])\n", - " values.append(height)\n", - " edges.append(period['location']+period['width'])\n", - " values.append(0)\n", - " edges.append(edges[-1]+1)\n", - " return(edges, values)\n", "\n", "\n", - "def plot_draw_graph(ax, data, color, label, height=1):\n", - " edges, values = make_edges_and_values(data, height=height)\n", - " patch = StepPatch(values=values, edges=edges, color=color, label=label)\n", - " ax.add_patch(patch)\n", - " ax.set_xlim(time_axis[0], time_axis[-1])\n", - " ax.set_ylim(min(0, 2*height), max(0, 2*height))\n", + "def plot_draw_graph(ax, start_time, end_time, data, color, label, height=1):\n", + " for i in range(0, len(data)):\n", + " period = data[i]\n", + " if i == 0:\n", + " ax.bar([period['location'] + 0.5 * period['width']], [height], width=period['width'], color=color, label=label)\n", + " else:\n", + " ax.bar([period['location'] + 0.5 * period['width']], [height], width=period['width'], color=color)\n", + " ax.set_xlim(start_time, end_time)\n", + " ax.set_ylim(min(0, 1.5*height), max(0, 1.5*height))\n", " ax.tick_params(left=False, labelleft=False)\n", + " ax.tick_params(bottom=False, labelbottom=False)\n", " ax.legend()\n", "\n", " \n", - "def plot(rest, sleep, bedtime):\n", - " fig, axs = plt.subplots(3, 1, figsize=(10,4))\n", - " plot_draw_graph(axs[0], sleep, \"C2\", \"sleep periods\")\n", - " plot_draw_graph(axs[1], rest, \"C8\", \"rest periods\", height=-1)\n", - " plot_draw_graph(axs[2], bed_time, \"C7\", \"main bed time\")\n", + "def plot(start_time, end_time, bed_time, rests):\n", + " fig, axs = plt.subplots(2, 1, figsize=(10,3))\n", + " plot_draw_graph(axs[0], start_time, end_time, rests, \"C8\", \"rest periods\")\n", + " plot_draw_graph(axs[1], start_time, end_time, bed_time, \"C7\", \"main bed time\", height=-1)\n", " plt.show()" ] }, @@ -237,69 +207,81 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Generate and plot" + "## 4. Export functions\n", + "\n", + "And these functions convert the start and end points in the time series to a human-readable format." ] }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 8, "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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knKv3dfw7Ok3i07no4/e6Yy+AIX/xjr+jBc7bXt7+v73v88VV1xBnz59On3b1dXVzJ07l7vuuqvN61RUVFBdXc2AAQf3f6GVJKk72+8jPJ0Zdtq7vZQSu3btatf2v//97/PnP/+5vd3ap507d1JVVdWusCNJkrrGQXdKa8OGDXzuc5/ja1/7GkOHDuXNN99kzpw5jBo1ilNOOYWbbroJgO3bt3PeeecxfPhwhg4dyvz587nrrrvYuHEjEydOZOLEiXttu6KigmuvvZZhw4YxevRoamtrAdi8eTMXXXQRo0aNYtSoUSxevBiAm2++mcsuu4xx48Zx2WWXsXDhQs4//3wAtmzZwgUXXMApp5zCmDFjePnllwGor69n8uTJDBkyhK9//euklFrsryRJ6hz7fUqrGNatW8cDDzzAmDFjWLBgAevWrWPp0qWklPjSl77ECy+8wObNmxk0aBBPPvkkAFu3bqV///7ceeedPPfccy2eQurfvz8rV65k7ty5XH311fznf/4nV111FTNmzOCMM87gD3/4A+eeey5r1qwBYPXq1SxatIjDDz+chQsXNm7npptuYuTIkTzxxBM8++yzfO1rX2P58uXccsstnHHGGcyePZsnn3ySe++9F4Bf//rXe/VXkiR1joMy8Bx//PGMGTMGgAULFrBgwQJGjhwJwLZt21i3bh3jx4/nmmuuYdasWZx//vmMHz++Tdu+5JJLGu9nzJgBwDPPPMPq1asbl3n//ffZtm0bAF/60pc4/PDD99rOokWLeOyxxwA4++yzqa+v5/333+eFF17g8ccfB+C8887j6KOPBmDYsGEd6q8kSdq3gzLw9O3bt3E6pcT111/PN77xjb2WW7ZsGb/85S+58cYbmTRpErNnz97ntpt+/PuT6V27drFkyRJKS0tb7cv+GDx4cIf6K0mS9u2gu4ZnT+eeey733Xdf4xGXt956i7fffpuNGzfSp08fLr30UmbOnMmyZcsA6NevHx988EGL2/vk2pn58+czduxYACZPnswPfvCDxmWWL1++z36NHz+eBx98EICFCxcyYMAAjjzySM4880weeughAH71q1/x7rvvArTYX0mStP/2+wjPYYcN6PSPpbfH5MmTWbNmTWM4OeKII/jJT35CbW0tM2fOpEePHpSUlPDjH/8YgCuuuIIpU6YwaNAgnnvuub229+6773LK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\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ - "bed_time, pre_bed_time_rests, bed_time_rests, post_bed_time_rests, sleep_periods = make_signal()\n", - "plot(pre_bed_time_rests + bed_time_rests + post_bed_time_rests, sleep_periods, bed_time)" + "def number2time(number):\n", + " hours = int(number / 60)\n", + " minutes = int(number - (hours*60))\n", + " return(str(hours)+\":\"+str(minutes).zfill(2))\n", + " \n", + "\n", + "def print_data(data, data_name):\n", + " print(data_name+ \" starts:\", end=\" \")\n", + " for peak in data:\n", + " print(number2time(round(peak['location'])), end=\" \")\n", + " print(\"\\n\" + data_name + \" ends: \", end=\" \")\n", + " for peak in data:\n", + " print(number2time(round(peak['location'] + peak['width'])), end=\" \")\n", + " print()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "## Export" + "## 5. Generate, plot and export\n", + "\n", + "Finally we generate the time series: from a start of noon (12:00) until noon next day (36:00) with bed time starting between 22:00 and 02:00 (26:00) and lasting between six and nine hours. Bed time include between one and three rest periods while before bed time there can be up to five rest periods and after bed time at most one. Bed time rests last between two and eight hours while other rests last between 0.2 hours and 0.5 hours. We check the time series by plotting it and inspecting the start and end points of the different periods." ] }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 9, "metadata": {}, "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, { "name": "stdout", "output_type": "stream", "text": [ - "Rest starts: 844 1043 1451 1756 2042 \n", - "Rest ends: 871 1072 1688 1882 2054 \n", - "Sleep starts: 1054 1509 1760 \n", - "Sleep ends: 1071 1630 1831 \n", - "Bed time starts: 1445 \n", - "Bed time ends: 1961 \n" + " Rest starts: 17:49 22:18 24:51 27:11 35:30 \n", + " Rest ends: 18:12 22:35 25:18 30:08 35:43 \n", + "Bed time starts: 25:34 \n", + "Bed time ends: 31:40 \n" ] } ], "source": [ - "def print_data(data, data_name):\n", - " print(data_name+ \" starts:\", end=\" \")\n", - " for peak in data:\n", - " print(round(peak['location']), end=\" \")\n", - " print(\"\\n\" + data_name + \" ends:\", end=\" \")\n", - " for peak in data:\n", - " print(round(peak['location'] + peak['width']), end=\" \")\n", - " print()\n", - " \n", - "print_data(pre_bed_time_rests + bed_time_rests + post_bed_time_rests, \"Rest\")\n", - "print_data(sleep_periods, \"Sleep\")\n", + "bed_time, rests = make_signal(start_time=12, end_time=36, \n", + " bed_time_start_minimum=22, bed_time_start_maximum=26, \n", + " bed_time_minimum=6, bed_time_maximum=9,\n", + " bed_time_iterations_minimum=1, bed_time_iterations_maximum=3,\n", + " pre_bed_time_iterations_minimum=0, pre_bed_time_iterations_maximum=5,\n", + " post_bed_time_iterations_minimum=0, post_bed_time_iterations_maximum=1,\n", + " bed_time_rest_minimum=2, bed_time_rest_maximum=8,\n", + " other_rest_minimum=0.2, other_rest_maximum=0.5)\n", + "\n", + "plot(12 * 60, 36*60, bed_time, rests)\n", + "\n", + "print_data(rests, \" Rest\")\n", "print_data(bed_time, \"Bed time\")" ] }, @@ -313,9 +295,9 @@ ], "metadata": { "kernelspec": { - "display_name": "sequgen-notebooks", + "display_name": "python37", "language": "python", - "name": "sequgen-notebooks" + "name": "python37" }, "language_info": { "codemirror_mode": { @@ -327,7 +309,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.5" + "version": "3.7.3" } }, "nbformat": 4, From e72d1f2dd76e9cd9a93160ac29fa0704e9d0a0f0 Mon Sep 17 00:00:00 2001 From: Erik Tjong Kim Sang Date: Wed, 7 Apr 2021 12:46:06 +0200 Subject: [PATCH 5/5] introduced person profile --- ggir-use-case-1.ipynb | 58 ++++++++++++++++++++----------------------- 1 file changed, 27 insertions(+), 31 deletions(-) diff --git a/ggir-use-case-1.ipynb b/ggir-use-case-1.ipynb index 9b0675a..4a94c91 100644 --- a/ggir-use-case-1.ipynb +++ b/ggir-use-case-1.ipynb @@ -93,24 +93,17 @@ "metadata": {}, "outputs": [], "source": [ - "def make_signal(start_time, end_time, \n", - " bed_time_start_minimum, bed_time_start_maximum, \n", - " bed_time_minimum, bed_time_maximum,\n", - " bed_time_iterations_minimum, bed_time_iterations_maximum,\n", - " pre_bed_time_iterations_minimum, pre_bed_time_iterations_maximum,\n", - " post_bed_time_iterations_minimum, post_bed_time_iterations_maximum,\n", - " bed_time_rest_minimum, bed_time_rest_maximum,\n", - " other_rest_minimum, other_rest_maximum):\n", - " bed_time = make_bed_time(bed_time_start_minimum, bed_time_start_maximum, bed_time_minimum, bed_time_maximum)\n", - " pre_bed_time_rests = make_rests(start_time * 60, bed_time[0]['location'], \n", - " other_rest_minimum * 60, other_rest_maximum * 60, \n", - " pre_bed_time_iterations_minimum, pre_bed_time_iterations_maximum)\n", + "def make_signal(profile):\n", + " bed_time = make_bed_time(profile['bed_time_start'][0], profile['bed_time_start'][1], profile['bed_time_width'][0], profile['bed_time_width'][1])\n", + " pre_bed_time_rests = make_rests(profile['time_frame'][0] * 60, bed_time[0]['location'], \n", + " profile['other_rest_width'][0] * 60, profile['other_rest_width'][1] * 60, \n", + " profile['pre_bed_time_iterations'][0], profile['pre_bed_time_iterations'][1])\n", " bed_time_rests = make_rests(bed_time[0]['location'], bed_time[0]['location']+bed_time[0]['width'],\n", - " bed_time_rest_minimum * 60, bed_time_rest_maximum * 60,\n", - " bed_time_iterations_minimum, bed_time_iterations_maximum)\n", - " post_bed_time_rests = make_rests(bed_time[0]['location']+bed_time[0]['width'], end_time*60,\n", - " other_rest_minimum * 60, other_rest_maximum * 60,\n", - " post_bed_time_iterations_minimum, post_bed_time_iterations_maximum)\n", + " profile['bed_time_rest_width'][0] * 60, profile['bed_time_rest_width'][1] * 60,\n", + " profile['bed_time_iterations'][0], profile['bed_time_iterations'][1])\n", + " post_bed_time_rests = make_rests(bed_time[0]['location']+bed_time[0]['width'], profile['time_frame'][1]*60,\n", + " profile['other_rest_width'][0] * 60, profile['other_rest_width'][1] * 60,\n", + " profile['post_bed_time_iterations'][0], profile['post_bed_time_iterations'][1])\n", " return(bed_time, (pre_bed_time_rests + bed_time_rests + post_bed_time_rests))" ] }, @@ -240,7 +233,7 @@ "source": [ "## 5. Generate, plot and export\n", "\n", - "Finally we generate the time series: from a start of noon (12:00) until noon next day (36:00) with bed time starting between 22:00 and 02:00 (26:00) and lasting between six and nine hours. Bed time include between one and three rest periods while before bed time there can be up to five rest periods and after bed time at most one. Bed time rests last between two and eight hours while other rests last between 0.2 hours and 0.5 hours. We check the time series by plotting it and inspecting the start and end points of the different periods." + "Finally we generate the time series from a person profile which is defined like this: the main time frame runs from noon (12:00) until noon next day (36:00) with bed time starting between 22:00 and 02:00 (26:00) and lasting between six and nine hours. Bed time include between one and three rest periods while before bed time there can be up to five rest periods and after bed time at most one. Bed time rests last between two and eight hours while other rests last between 0.2 hours and 0.5 hours. We check the time series by plotting it and inspecting the start and end points of the different periods." ] }, { @@ -250,7 +243,7 @@ "outputs": [ { "data": { - "image/png": "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\n", + "image/png": "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\n", "text/plain": [ "
" ] @@ -262,22 +255,25 @@ "name": "stdout", "output_type": "stream", "text": [ - " Rest starts: 17:49 22:18 24:51 27:11 35:30 \n", - " Rest ends: 18:12 22:35 25:18 30:08 35:43 \n", - "Bed time starts: 25:34 \n", - "Bed time ends: 31:40 \n" + " Rest starts: 13:22 19:47 22:03 26:13 30:33 34:43 \n", + " Rest ends: 13:51 20:11 22:22 28:25 32:37 35:08 \n", + "Bed time starts: 24:51 \n", + "Bed time ends: 32:59 \n" ] } ], "source": [ - "bed_time, rests = make_signal(start_time=12, end_time=36, \n", - " bed_time_start_minimum=22, bed_time_start_maximum=26, \n", - " bed_time_minimum=6, bed_time_maximum=9,\n", - " bed_time_iterations_minimum=1, bed_time_iterations_maximum=3,\n", - " pre_bed_time_iterations_minimum=0, pre_bed_time_iterations_maximum=5,\n", - " post_bed_time_iterations_minimum=0, post_bed_time_iterations_maximum=1,\n", - " bed_time_rest_minimum=2, bed_time_rest_maximum=8,\n", - " other_rest_minimum=0.2, other_rest_maximum=0.5)\n", + "profile = { 'time_frame': [12, 36],\n", + " 'bed_time_start': [22, 26],\n", + " 'bed_time_width': [6, 9],\n", + " 'bed_time_iterations': [1, 3],\n", + " 'pre_bed_time_iterations': [0, 5],\n", + " 'post_bed_time_iterations': [0, 1],\n", + " 'bed_time_rest_width': [2, 8],\n", + " 'other_rest_width': [0.2, 0.5]\n", + " }\n", + "\n", + "bed_time, rests = make_signal(profile)\n", "\n", "plot(12 * 60, 36*60, bed_time, rests)\n", "\n",