Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Auto-convert "greek small letter mu" to micro symbol #47

Merged
merged 6 commits into from Nov 6, 2020
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
18 changes: 18 additions & 0 deletions .github/workflows/python_tests.yml
Expand Up @@ -5,6 +5,12 @@ on:
branches: [ master ]
pull_request:
branches: [ master ]
create:
branches: [master]
tags: ['**']
schedule:
- cron: "0 4 1 * *"
sappelhoff marked this conversation as resolved.
Show resolved Hide resolved


jobs:
build:
Expand All @@ -14,6 +20,10 @@ jobs:
platform: [ubuntu-18.04, ubuntu-latest, macos-latest, windows-latest]
python-version: [3.8]

env:
TZ: Europe/Berlin
FORCE_COLOR: true

runs-on: ${{ matrix.platform }}

steps:
Expand All @@ -36,6 +46,14 @@ jobs:
run: |
pip install -U https://api.github.com/repos/mne-tools/mne-python/zipball/master

- name: Display versions and environment information
run: |
echo $TZ
date
python --version
which python
mne sys_info

- name: Check formatting
if: "matrix.platform == 'ubuntu-18.04'"
run: |
Expand Down
11 changes: 7 additions & 4 deletions README.rst
Expand Up @@ -22,9 +22,10 @@
pybv
====

``pybv`` is a lightweight exporter to the BrainVision data format. It is meant
for use with electrophysiology datasets stored in the
`Brain Imaging Data Structure <https://bids.neuroimaging.io>`_.
``pybv`` is a lightweight exporter to the BrainVision data format.

The BrainVision data format is a recommended data format
for use in the `Brain Imaging Data Structure <https://bids.neuroimaging.io>`_.


The documentation can be found under the following links:
Expand Down Expand Up @@ -64,9 +65,11 @@ as hosted by Brain Products.
Installation
============

``pybv`` runs on Python version 3.6 or higher.

``pybv``'s only dependency is ``numpy``. However, we currently recommend that
you install MNE-Python for reading BrainVision data. See their instructions
`here <https://www.martinos.org/mne/stable/install_mne_python.html>`_.
`here <https://mne.tools/stable/install/index.html>`_.

After you have a working installation of MNE-Python (or only ``numpy`` if you
don't want to read data and only write it), you can install ``pybv`` through
Expand Down
32 changes: 25 additions & 7 deletions pybv/io.py
Expand Up @@ -13,18 +13,21 @@
import datetime
import os
import os.path as op
import warnings

import numpy as np

from pybv import __version__

# ASCII as future formats
supported_formats = {
SUPPORTED_FORMATS = {
'binary_float32': ('IEEE_FLOAT_32', np.float32),
'binary_int16': ('INT_16', np.int16),
}

supported_orients = {'multiplexed'}
SUPPORTED_ORIENTS = {'multiplexed'}

SUPPORTED_UNITS = ['V', 'mV', 'µV', 'uV', 'nV']


def write_brainvision(data, sfreq, ch_names, fname_base, folder_out,
Expand Down Expand Up @@ -120,6 +123,15 @@ def write_brainvision(data, sfreq, ch_names, fname_base, folder_out,

_chk_fmt(fmt)

if unit == 'μV':
# this is greek mu: μ
# https://www.compart.com/de/unicode/U+03BC
warnings.warn(
f"Encountered small greek letter mu: 'μ' in unit: {unit} ... "
f"converting to micro sign: 'µ': {unit.replace('μ', 'µ')}"
)
unit = 'µV'

# measurement date
if not isinstance(meas_date, (str, datetime.datetime, type(None))):
raise ValueError('`meas_date` must be of type str, datetime.datetime, '
Expand All @@ -145,21 +157,21 @@ def write_brainvision(data, sfreq, ch_names, fname_base, folder_out,

def _chk_fmt(fmt):
"""Check that the format string is valid, return BVEF / numpy datatypes."""
if fmt not in supported_formats:
if fmt not in SUPPORTED_FORMATS:
errmsg = ('Data format {} not supported.'.format(fmt) +
'Currently supported formats are: ' +
', '.join(supported_formats))
', '.join(SUPPORTED_FORMATS))
raise ValueError(errmsg)
return supported_formats[fmt]
return SUPPORTED_FORMATS[fmt]


def _chk_multiplexed(orientation):
"""Validate an orientation, return if it is multiplexed or not."""
orientation = orientation.lower()
if orientation not in supported_orients:
if orientation not in SUPPORTED_ORIENTS:
errmsg = ('Orientation {} not supported.'.format(orientation) +
'Currently supported orientations are: ' +
', '.join(supported_orients))
', '.join(SUPPORTED_ORIENTS))
raise ValueError(errmsg)
return orientation == 'multiplexed'

Expand Down Expand Up @@ -225,6 +237,12 @@ def _optimize_channel_unit(resolution, unit):
return resolution / 1e-6, 'µV'
elif unit == 'nV':
return resolution / 1e-9, 'nV'
else:
raise ValueError(
f'Encountered unsupported unit: {unit}'
'\nUse either "None" for `unit`, or one of the units: '
f'{SUPPORTED_UNITS}'
)


def _write_vhdr_file(vhdr_fname, vmrk_fname, eeg_fname, data, sfreq, ch_names,
Expand Down
15 changes: 12 additions & 3 deletions pybv/tests/test_bv_writer.py
Expand Up @@ -123,10 +123,19 @@ def test_write_read_cycle(meas_date):
# check that we create a folder that does not yet exist
tmpdir = op.join(tmpdir, 'newfolder')

# First fail writing due to wrong unit
unsupported_unit = "rV"
with pytest.raises(ValueError, match='Encountered unsupported unit'):
write_brainvision(data, sfreq, ch_names, fname, tmpdir,
unit=unsupported_unit)

# write and read data to BV format
write_brainvision(data, sfreq, ch_names, fname, tmpdir, events=events,
resolution=np.power(10., -np.arange(10)),
meas_date=meas_date)
# ensure that greek small letter mu gets converted to micro sign
with pytest.warns(UserWarning):
write_brainvision(data, sfreq, ch_names, fname, tmpdir, events=events,
resolution=np.power(10., -np.arange(10)),
unit='μV',
meas_date=meas_date)
vhdr_fname = op.join(tmpdir, fname + '.vhdr')
raw_written = mne.io.read_raw_brainvision(vhdr_fname, preload=True)
# delete the first annotation because it's just marking a new segment
Expand Down
25 changes: 13 additions & 12 deletions setup.py
Expand Up @@ -33,8 +33,6 @@


if __name__ == "__main__":
if os.path.exists('MANIFEST'):
os.remove('MANIFEST')

setup(name=DISTNAME,
maintainer=MAINTAINER,
Expand All @@ -48,16 +46,19 @@
long_description=open('README.rst').read(),
long_description_content_type='text/x-rst',
zip_safe=True, # the package can run out of an .egg file
classifiers=['Intended Audience :: Science/Research',
'Intended Audience :: Developers',
'License :: OSI Approved',
'Programming Language :: Python',
'Topic :: Software Development',
'Topic :: Scientific/Engineering',
'Operating System :: Microsoft :: Windows',
'Operating System :: POSIX',
'Operating System :: Unix',
'Operating System :: MacOS'],
python_requires='~=3.6',
classifiers=[
'Intended Audience :: Science/Research',
'Intended Audience :: Developers',
'License :: OSI Approved',
'Programming Language :: Python',
'Topic :: Software Development',
'Topic :: Scientific/Engineering',
'Operating System :: Microsoft :: Windows',
'Operating System :: POSIX',
'Operating System :: Unix',
'Operating System :: MacOS'
],
platforms='any',
keywords='Brain Products BrainVision vhdr vmrk eeg',
packages=find_packages(),
Expand Down