{ "cells": [ { "cell_type": "markdown", "id": "0acb0526-fb21-42f5-8980-7be07e62c649", "metadata": {}, "source": [ "# Getting started\n", "\n", "This document is intended to get you started as quickly as possible. We discuss two important underlying concepts, the package's core classes and how to combine them, and we end with a simple example in which we create a trial as might be used in an auditory perception experiment." ] }, { "cell_type": "code", "execution_count": 3, "id": "00437417-8bbb-48b1-bc41-b96e3479cf52", "metadata": { "nbsphinx": "hidden", "tags": [] }, "outputs": [], "source": [ "# We suppress warnings, but let's hide that to avoid confusion\n", "import warnings\n", "warnings.filterwarnings('ignore')\n", "%matplotlib inline" ] }, { "cell_type": "markdown", "id": "823fb570-f970-46c8-bf7d-590215b9b51c", "metadata": { "tags": [] }, "source": [ "## Step 1: Concepts\n", "\n", "Consider the example sequence given below:" ] }, { "cell_type": "raw", "id": "a001a224-c82f-4216-87de-3fe77184657a", "metadata": { "raw_mimetype": "text/restructuredtext", "tags": [] }, "source": [ ".. figure:: gettingstarted_0.png\n", " :align: center\n", " \n", " An example sequence or rhythm. Each event (in most cases, a sound) is presented at a specific \n", " point in time: the event onset. The difference in time between the onset of one event and the \n", " onset of the next event we call the inter-onset interval (IOI)." ] }, { "cell_type": "markdown", "id": "ce29dbfe-7d5e-488c-a3f9-2061564a1251", "metadata": { "tags": [] }, "source": [ "### Inter-onset intervals (IOIs) and onsets\n", "For timing sequences and events, throughout this package we make the most use of inter-onset intervals (IOIs). IOIs represent the interval between the onset of one event, and the onset of the next event. Because IOIs are onset-to-onset, which is different from inter-stimulus intervals (which are offset-to-onset), we can think about these sequences in terms of rhythms. This because often the duration of the event is irrelevant to the type of beat that is induced in the listener." ] }, { "cell_type": "raw", "id": "a049c7a5-6b15-443c-8209-1dbceb777995", "metadata": { "raw_mimetype": "text/restructuredtext", "tags": [] }, "source": [ "Onsets (i.e. *t* values) are used internally, and only in some special cases. When creating sequences on the basis of IOIs, it is assumed that the first onset is at *t* = 0. However, you can create sequences with a different onset than zero, for that see :py:meth:`thebeat.core.Sequence.from_onsets`." ] }, { "cell_type": "markdown", "id": "7982c8c4-15c2-4241-abb0-2478f657f8d4", "metadata": { "tags": [] }, "source": [ "### End sequence with event or interval\n", "An important concept to mention here is that sequences can end with an event, or end with an interval. In effect, this means that sequences that end with an event have *n* events, but *n*-1 IOIs. Sequences that end with an interval have *n* events and *n* IOIs. The default is for sequences to end with an event, but for rhythms or for combining sequences we need sequences that end with an interval. Otherwise, we would not know what interval to place between the offset of the final event in a sequence and the onset of the first event in the next sequence." ] }, { "cell_type": "raw", "id": "82a756e5-2159-419c-ac46-e250bb2d208e", "metadata": { "raw_mimetype": "text/restructuredtext", "tags": [] }, "source": [ "To end sequences with an interval, we pass ``end_with_interval=True`` to the :py:class:`~thebeat.core.Sequence` constructor." ] }, { "cell_type": "markdown", "id": "1d278653-d3e3-42b1-a8a2-2b42cd6f5099", "metadata": { "raw_mimetype": "text/restructuredtext", "tags": [] }, "source": [ "## Step 2: Combining and converting between classes" ] }, { "cell_type": "raw", "id": "ed6b0c66-c1dc-4e82-bb0f-cbc2ad8028b1", "metadata": { "raw_mimetype": "text/restructuredtext", "tags": [] }, "source": [ "This visualization displays the major classes that are used throughout this package.\n", "\n", "Some of them we can combine into other ones:\n", "\n", ".. figure:: images/core_classes.png\n", "\n", ":py:class:`~thebeat.core.Sequence` and :py:class:`~thebeat.music.Rhythm` objects contain only timing information. :py:class:`~thebeat.core.SoundStimulus` objects contain acoustic information. \n", "\n", "Trials are made from combining a :py:class:`~thebeat.core.SoundStimulus` and :py:class:`~thebeat.core.Sequence` object into a :py:class:`~thebeat.core.SoundSequence` object which contains both audio and timing information. You can either pass the :py:class:`~thebeat.core.SoundSequence` one or multiple (i.e. one for each event) :py:class:`~thebeat.core.SoundStimulus` objects. \n", "\n", ":py:class:`~thebeat.music.Rhythm` objects first have to be converted to a :py:class:`~thebeat.core.Sequence` object before we can combine them into a :py:class:`~thebeat.core.SoundSequence` trial (using the :py:meth:`~thebeat.music.Rhythm.to_sequence` method). Finally, from a :py:class:`~thebeat.music.Rhythm` we can make a :py:class:`~thebeat.music.Melody`.\n" ] }, { "cell_type": "markdown", "id": "84615bc4-4d95-445a-b33d-af5bbc5ef556", "metadata": { "raw_mimetype": "text/html", "tags": [] }, "source": [ "