Skip to content

Commit

Permalink
Deploying to gh-pages from @ 1dd297b 🚀
Browse files Browse the repository at this point in the history
  • Loading branch information
github-actions[bot] committed Dec 12, 2024
0 parents commit e45eb04
Show file tree
Hide file tree
Showing 153 changed files with 15,684 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# macOS
.DS_Store
Empty file added .nojekyll
Empty file.
1 change: 1 addition & 0 deletions CNAME
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
nmod-wiki.fcbg.ch
86 changes: 86 additions & 0 deletions _downloads/47d5cadb3294b342d3d7c9b46acc2465/precise_audio.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n\n# Precise audio presentation\n\n.. include:: ../../links.inc\n\nWhen delivering a sound through the soundcard of a computer and a trigger through the\nparallel port, it's important to ensure that the sound and the trigger are synchronized.\n\n## Python sleep precision\n\nThe :func:`time.sleep` function from the `time` module is not precise enough to halt the\nprogram execution for a precise amount of time. The variability depends on the operating\nsystem and python version and should be measured before using it in an experiment.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"import time\nimport timeit\n\nimport numpy as np\n\ntimes = timeit.repeat(\"time.sleep(0.005)\", repeat=3, number=100, globals=globals())\ntimes = np.array(times) / 100\nprint(f\"Mean: {np.mean(times):.8f} seconds\")\nprint(f\"Standard Deviation: {np.std(times):.8f} seconds\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Locally, I measured 5.06822 ms \u00b1 61.4 \u03bcs per loop (mean \u00b1 std. dev. of 3 runs, 100\nloop each).\n\nIf greater sleeping precision is needed, the sleeping period can be cut into segments\nwaited with :func:`time.sleep` and a last segment where a :func:`time.perf_counter` is\nused to wait for the remaining time.\n\n<div class=\"alert alert-info\"><h4>Note</h4><p>Note that using :func:`time.sleep` is important as it gives back the control to\n the operating system, allowing other processes to run.</p></div>\n\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"def high_precision_sleep(duration: float) -> None:\n \"\"\"High precision sleep function.\"\"\"\n start_time = time.perf_counter()\n assert 0 < duration, \"The duration must be strictly positive.\"\n while True:\n elapsed_time = time.perf_counter() - start_time\n remaining_time = duration - elapsed_time\n if remaining_time <= 0:\n break\n if remaining_time >= 0.0002:\n time.sleep(remaining_time / 2)\n\n\ntimes = timeit.repeat(\n \"high_precision_sleep(0.005)\", repeat=3, number=100, globals=globals()\n)\ntimes = np.array(times) / 100\nprint(f\"Mean: {np.mean(times):.8f} seconds\")\nprint(f\"Standard Deviation: {np.std(times):.8f} seconds\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Locally, I measured 5.00070 ms \u00b1 0.08 \u03bcs per loop (mean \u00b1 std. dev. of 3 runs, 100\nloop each).\n\n## Psychopy and Psychtoolbox\n\n`Psychtoolbox`_ is a compiled toolbox for MATLAB that allows to present stimuli with\nprecision. Despite a lack of funding and resources to support it, it's still one of\nthe most used stimuli presentation toolboxes. Some of its functionalities are\navailable in Python, especially through the `Psychopy`_ library.\n\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"# In this example, we will use the python interface of `Psychtoolbox`_ combined with\n# triggers from :class:`byte_triggers.ParallelPortTrigger` to deliver synchronize audio\n# stimuli and triggers.\n\nimport psychtoolbox as ptb\nfrom byte_triggers import ParallelPortTrigger\nfrom psychopy.sound.backend_ptb import SoundPTB\n\n# create the sound and trigger object\nsound = SoundPTB(value=440.0, secs=0.2, blockSize=16)\ntrigger = ParallelPortTrigger(0x2FB8) # or \"/dev/parport0\" on linux\n\n# loop 10 times and deliver 10 sounds\nfor k in range(10):\n now = ptb.GetSecs()\n sound.play(when=now + 0.2) # schedule the sound in 200 ms\n high_precision_sleep(0.2) # wait for 200 ms\n trigger.signal(1) # send the trigger\n print(f\"Sound {k + 1} delivered.\")\n high_precision_sleep(0.5) # wait between sounds"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The key elements are to schedule the sound with the ``when`` argument of the\n`Psychtoolbox`_ backend, wait for the scheduling duration, and deliver the trigger.\nWith this method, the trigger to sound delay should be less than 1 ms.\n\n.. figure:: ../../_static/tutorials/trigger-sound-delay-epochs.png\n :align: center\n :alt: Epochs showing the trigger to sound delay\n\nThe measure above was done with a 1024 Hz sampling rate on an ANT Neuro EEG system.\nMeasuring algorithmically the delay between the trigger and the sound is possible\nthrough a threshold on the absolute value of the hilbert transformed signal, yielding:\n\n.. figure:: ../../_static/tutorials/trigger-sound-delay-hist.png\n :align: center\n :alt: Epochs showing the trigger to sound delay\n\n<div class=\"alert alert-info\"><h4>Note</h4><p>Note that the measure through the absolute value of the hilbert transformed signal\n is a good automatic sound onset detection method, but it's not perfect and the\n thresholding inherently adds jitter to the measure.</p></div>\n\n"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"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.10"
}
},
"nbformat": 4,
"nbformat_minor": 0
}
120 changes: 120 additions & 0 deletions _downloads/49f80d834377661287b94f28d7832e8e/precise_audio.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
"""
.. _tut-precise-audio:
Precise audio presentation
==========================
.. include:: ../../links.inc
When delivering a sound through the soundcard of a computer and a trigger through the
parallel port, it's important to ensure that the sound and the trigger are synchronized.
Python sleep precision
----------------------
The :func:`time.sleep` function from the `time` module is not precise enough to halt the
program execution for a precise amount of time. The variability depends on the operating
system and python version and should be measured before using it in an experiment.
"""

# sphinx_gallery_thumbnail_path = '_static/tutorials/trigger-sound-delay-hist.png'

import time
import timeit

import numpy as np

times = timeit.repeat("time.sleep(0.005)", repeat=3, number=100, globals=globals())
times = np.array(times) / 100
print(f"Mean: {np.mean(times):.8f} seconds")
print(f"Standard Deviation: {np.std(times):.8f} seconds")

# %%
# Locally, I measured 5.06822 ms ± 61.4 μs per loop (mean ± std. dev. of 3 runs, 100
# loop each).
#
# If greater sleeping precision is needed, the sleeping period can be cut into segments
# waited with :func:`time.sleep` and a last segment where a :func:`time.perf_counter` is
# used to wait for the remaining time.
#
# .. note::
#
# Note that using :func:`time.sleep` is important as it gives back the control to
# the operating system, allowing other processes to run.


def high_precision_sleep(duration: float) -> None:
"""High precision sleep function."""
start_time = time.perf_counter()
assert 0 < duration, "The duration must be strictly positive."
while True:
elapsed_time = time.perf_counter() - start_time
remaining_time = duration - elapsed_time
if remaining_time <= 0:
break
if remaining_time >= 0.0002:
time.sleep(remaining_time / 2)


times = timeit.repeat(
"high_precision_sleep(0.005)", repeat=3, number=100, globals=globals()
)
times = np.array(times) / 100
print(f"Mean: {np.mean(times):.8f} seconds")
print(f"Standard Deviation: {np.std(times):.8f} seconds")

# %%
# Locally, I measured 5.00070 ms ± 0.08 μs per loop (mean ± std. dev. of 3 runs, 100
# loop each).
#
# Psychopy and Psychtoolbox
# -------------------------
#
# `Psychtoolbox`_ is a compiled toolbox for MATLAB that allows to present stimuli with
# precision. Despite a lack of funding and resources to support it, it's still one of
# the most used stimuli presentation toolboxes. Some of its functionalities are
# available in Python, especially through the `Psychopy`_ library.

# In this example, we will use the python interface of `Psychtoolbox`_ combined with
# triggers from :class:`byte_triggers.ParallelPortTrigger` to deliver synchronize audio
# stimuli and triggers.

import psychtoolbox as ptb
from byte_triggers import ParallelPortTrigger
from psychopy.sound.backend_ptb import SoundPTB

# create the sound and trigger object
sound = SoundPTB(value=440.0, secs=0.2, blockSize=16)
trigger = ParallelPortTrigger(0x2FB8) # or "/dev/parport0" on linux

# loop 10 times and deliver 10 sounds
for k in range(10):
now = ptb.GetSecs()
sound.play(when=now + 0.2) # schedule the sound in 200 ms
high_precision_sleep(0.2) # wait for 200 ms
trigger.signal(1) # send the trigger
print(f"Sound {k + 1} delivered.")
high_precision_sleep(0.5) # wait between sounds

# %%
# The key elements are to schedule the sound with the ``when`` argument of the
# `Psychtoolbox`_ backend, wait for the scheduling duration, and deliver the trigger.
# With this method, the trigger to sound delay should be less than 1 ms.
#
# .. figure:: ../../_static/tutorials/trigger-sound-delay-epochs.png
# :align: center
# :alt: Epochs showing the trigger to sound delay
#
# The measure above was done with a 1024 Hz sampling rate on an ANT Neuro EEG system.
# Measuring algorithmically the delay between the trigger and the sound is possible
# through a threshold on the absolute value of the hilbert transformed signal, yielding:
#
# .. figure:: ../../_static/tutorials/trigger-sound-delay-hist.png
# :align: center
# :alt: Epochs showing the trigger to sound delay
#
# .. note::
#
# Note that the measure through the absolute value of the hilbert transformed signal
# is a good automatic sound onset detection method, but it's not perfect and the
# thresholding inherently adds jitter to the measure.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file added _images/back-panel.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added _images/bistim-coil-connection.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added _images/bistim-settings-epsilon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added _images/bistim-settings.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added _images/bistim-system.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added _images/connectors-dc-power.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added _images/connectors-electrodes.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added _images/device.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added _images/h4-dark.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added _images/h4-light.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added _images/interface.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added _images/magstim-buttons.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added _images/magstim-connector.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added _images/magstim-safety.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added _images/pdf.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added _images/sphx_glr_precise_audio_thumb.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added _images/splitter.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added _images/super-rapid-plus-coil.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added _images/super-rapid-plus-system.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added _images/tms-coil.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added _images/trigger-sound-delay-epochs.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added _images/trigger-sound-delay-hist.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 9 additions & 0 deletions _sources/api/generated/nmod_wiki.add_file_handler.rst.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
nmod\_wiki.add\_file\_handler
=============================

.. currentmodule:: nmod_wiki

.. autofunction:: add_file_handler

.. minigallery:: nmod_wiki.add_file_handler
:add-heading:
9 changes: 9 additions & 0 deletions _sources/api/generated/nmod_wiki.set_log_level.rst.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
nmod\_wiki.set\_log\_level
==========================

.. currentmodule:: nmod_wiki

.. autofunction:: set_log_level

.. minigallery:: nmod_wiki.set_log_level
:add-heading:
15 changes: 15 additions & 0 deletions _sources/api/index.rst.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
API References
==============

This is the reference for classes (``CamelCase`` names) and functions
(``underscore_case`` names) of ``nmod_wiki`` grouped thematically. This package can be
installed with ``pip`` from source:

.. code-block:: bash
$ pip install git+https://github.com/fcbg-platforms/nmod-wiki
.. toctree::
:maxdepth: 2

logging.rst
10 changes: 10 additions & 0 deletions _sources/api/logging.rst.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
Logging
=======

.. currentmodule:: nmod_wiki

.. autosummary::
:toctree: generated/

add_file_handler
set_log_level
62 changes: 62 additions & 0 deletions _sources/contributing.rst.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
.. include:: ./links.inc

Contributing Guide
==================

Tracker
-------

Contributions in all forms to this wiki are welcome. This wiki is hosted and build on
`GitHub <project github_>`_. The `issue tracker <project issue tracker_>`_ can be used
to propose changes, additions and report issues and solutions found when working with
neuromodulation data or devices from our site.

Pull Requests
-------------

If comfortable with git and collaborative development, pull request to the repository
are welcome. The wiki is organized as a python project with a sphinx documentation.
The documentation, used to generate the website HTML pages, is written in
`reStructuredText format <rst_>`_ in the `doc <project github doc_>`_ folder. For
instance, ``doc/datasheets.rst`` contains the content of the
:ref:`datasheets:Datasheets & Manuals` page.

In a pull request, the automatic workflows will build the documentation and check for
conformity. Any warnings and errors during the build process must be resolved before
the pull request can be merged.

Building the documentation locally
----------------------------------

To confirm that the documentation build without warning, it is possible to build the
documentation locally. After cloning the repository, the project and its dependencies
can be installed in a python environment with:

.. code-block:: bash
$ pip install -e path/to/nmod-wiki[all]
Additionally, `pre-commit`_ hooks are available to check for common errors before
committing changes.

.. code-block:: bash
$ pip install pre-commit
$ pre-commit install
The documentation can be build from the ``nmod-wiki/doc`` folder with ``make`` commands:

- ``make html`` to build the entire website.
- ``make html-noplot`` to build the website without running the tutorials.
- ``make clean`` to remove the generated and build files.
- ``make view`` to open the build website in the default browser.
- ``make linkcheck`` followed by ``make linkcheck-grep`` to test for broken URLs.

Tutorials
---------

Python-based tutorials and code snippet are executed using `sphinx-gallery`_. The
tutorials are written in a plain python ``.py`` file in the folder
``nmod-wiki/tutorials``. The file naming must follow the pattern ``dd_*.py`` with ``dd``
corresponding to 2 digits used to order the tutorials. The ``# %%`` jupyter syntax is
used to denote separate sections.
Loading

0 comments on commit e45eb04

Please sign in to comment.