Skip to content

Commit 6f26175

Browse files
committed
Update internal documentation and string formatting
1 parent 63c3c93 commit 6f26175

File tree

12 files changed

+163
-146
lines changed

12 files changed

+163
-146
lines changed

README.rst

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -26,37 +26,32 @@ The following external libraries are required:
2626
Installation
2727
------------
2828

29-
For performance and convenience reasons we highly recommend to use
30-
`Conda`_ (miniconda for simplicity) to manage your Python installation.
31-
Once installed, you can use the following steps to create a new environment
32-
with the *sfa* toolbox.
29+
For performance and convenience reasons we highly recommend to use `Conda`_ (miniconda for simplicity) to manage your Python installation. Once installed, you can use the following steps to receive and use *sfa*, depending on your use case:
3330

34-
#. Create new Conda environment from the specified requirements:
35-
``conda env create --file environment.yml``
31+
A. By cloning (or downloading) the repository and setting up a new environment **[recommended]**:
3632

37-
#. Activate the environment:
38-
``source activate sfa``
33+
``git clone https://github.com/AppliedAcousticsChalmers/sound_field_analysis-py.git``
3934

40-
#. Install *sfa* from **either** source:
35+
``cd sound_field_analysis-py/``
4136

42-
By cloning (or downloading) the repository **[recommended]**:
37+
Create a new Conda environment from the specified requirements:
38+
``conda env create --file environment.yml``
4339

44-
``git clone https://github.com/AppliedAcousticsChalmers/sound_field_analysis-py.git``
40+
Activate the environment:
41+
``source activate sfa``
4542

46-
``cd sound_field_analysis-py/``
43+
**Optional:** Install additional requirements in case you want to locally run the *Jupyter Notebooks* with examples:
44+
``conda env update --file environment_jupyter.yml``
4745

48-
``pip install -e .``
46+
B. From PyPI **[NOT recommended - code outdated]**:
4947

50-
From `conda-forge`_ channel **[not recommended - code currently outdated]**:
48+
Install into an existing environment (without example *Jupyter Notebooks*):
49+
``pip install sound_field_analysis``
5150

52-
``conda install -c conda-forge sound_field_analysis``
51+
C. From `conda-forge`_ channel **[NOT recommended - code outdated]**:
5352

54-
From PyPI **[Not recommended - code currently outdated]**:
55-
56-
``pip install sound_field_analysis``
57-
58-
#. **Optional:** Install additional requirements in case you want to locally run *Jupyter Notebooks*:
59-
``conda env update --file environment_jupyter.yml``
53+
Install into an existing environment:
54+
``conda install -c conda-forge sound_field_analysis``
6055

6156

6257
Documentation
@@ -113,6 +108,9 @@ miro or `SOFA`_ files.
113108
Version history
114109
---------------
115110

111+
*v2019.11.6*
112+
* Update of internal documentation and string formatting
113+
116114
*v2019.8.15*
117115
* Change of version number scheme to CalVer
118116
* Improvement of Exp4

contribute.md

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,29 +2,28 @@
22
## Dev environment
33
Given you have [anaconda](https://www.continuum.io/downloads) installed, run the following commands to clone the repository into a new folder `sound_field_analysis-py`, install necessary tools into a new conda environment and activate it:
44
```
5-
git clone https://github.com/QULab/sound_field_analysis-py.git
6-
conda create -n sfa_dev scipy numpy plotly pip ipython
7-
source activate sfa_dev
8-
pip install -e sound_field_analysis-py
5+
git clone https://github.com/AppliedAcousticsChalmers/sound_field_analysis-py.git
6+
cd sound_field_analysis-py/
7+
conda env create --file environment.yml
8+
source activate sfa
99
```
10-
You can now work on the *sfa* toolbox inside the `sound_field_analysis-py` folder. Using `ipython`, you may use the following magic commands to ensure reload on any changes inside the package:
10+
11+
You can now work on the *sfa* toolbox inside the `sound_field_analysis-py` folder. Using `ipython`, you may use the following magic commands to ensure reload on any changes inside the package:
1112
```
1213
%load_ext autoreload
1314
%autoreload 2
1415
```
1516

1617
## Documentation
1718
If you want to compile the documentation (pdf and/or html), you need to additionally install sphinx and sphinx_rtd_theme and clone the gh-pages branch:
18-
1919
```
20-
conda install sphinx sphinx_rtd_theme
21-
git clone --single-branch --branch gh-pages https://github.com/QULab/sound_field_analysis-py.git sound_field_analysis-docs
20+
conda env update --file environment_gh-pages.yml
21+
git clone --single-branch --branch gh-pages https://github.com/AppliedAcousticsChalmers/sound_field_analysis-py.git sound_field_analysis-docs
2222
```
2323

2424
Now you can compile the pdf readme (given you have latex installed) and html pages by running `make latexpdf` or `make html` from the `sound_field_analysis-py\doc` directory.
2525

2626
If you decide on a different folder structure, you may edit the following line in `doc/Makefile` to decide on where to move the html documentation:
27-
2827
```
2928
HTMLDIR = ../../sound_field_analysis-docs
3029
```

environment_gh-pages.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
channels:
2+
- defaults
3+
dependencies:
4+
- sphinx
5+
- sphinx_rtd_theme

setup.py

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,33 @@
1-
from setuptools import setup
2-
3-
version = open("sound_field_analysis/_version.py").readlines()[-1].split()[-1].strip("\"'")
1+
from setuptools import find_packages, setup
42

53
setup(
64
name='sound_field_analysis',
7-
version=version,
8-
description='Analyze, visualize and process sound field data recorded by spherical microphone arrays.',
95
url='https://github.com/AppliedAcousticsChalmers/sound_field_analysis-py/',
6+
version=open('sound_field_analysis/_version.py').readlines()[-1].split()[-1].strip('"\''),
7+
license='GPLv3',
8+
# license='MIT',
9+
10+
description='Analyze, visualize and process sound field data recorded by spherical microphone arrays.',
11+
long_description=open('README.rst', mode='r', encoding='utf-8').read(),
12+
keywords='sound field analysis spherical microphone array',
13+
1014
author='QU Lab / Christoph Hohnerlein',
15+
# author='Chalmers University of Technology / Jens Ahrens',
1116
author_email='[email protected]',
12-
license='GPLv3',
17+
# author_email='[email protected]',
18+
1319
classifiers=[
1420
'Development Status :: 4 - Beta',
21+
# 'Development Status :: 5 - Production/Stable',
1522
'Intended Audience :: Science/Research',
1623
'Topic :: Multimedia :: Sound/Audio',
1724
'License :: OSI Approved :: GNU General Public License v3 (GPLv3)',
18-
'Programming Language :: Python :: 3',
25+
# 'License :: OSI Approved :: MIT License',
26+
'Programming Language :: Python :: 3.7',
27+
'Operating System :: OS Independent',
1928
],
20-
keywords='sound field analysis spherical microphone array',
29+
30+
python_requires='>=3.7',
2131
install_requires=[
2232
'scipy',
2333
'numpy',
@@ -27,9 +37,11 @@
2737
package_data={
2838
'examples': ['examples'],
2939
},
40+
3041
extras_require={
3142
'plotting': ['plotly'],
3243
'examples': ['jupyter'],
3344
},
34-
packages=['sound_field_analysis'],
45+
46+
packages=find_packages(),
3547
)

sound_field_analysis/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
from ._version import __version__
44

5-
__all__ = ["io", "gen", "process", "sph", "utils", "lebedev"]
5+
__all__ = ['io', 'gen', 'process', 'sph', 'utils', 'lebedev']
66

77
try:
88
import plotly

sound_field_analysis/_version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
"""Version information."""
2-
__version__ = '2019.8.15'
2+
__version__ = '2019.11.7'

sound_field_analysis/gen.py

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
`gauss_grid`
77
Gauss-Legendre quadrature grid and weights
88
`lebedev`
9-
Lebedev quadrature grid and weigths
9+
Lebedev quadrature grid and weights
1010
`radial_filter`
1111
Modal radial filter
1212
`radial_filter_fullspec`
@@ -20,8 +20,8 @@
2020
from scipy.special import spherical_jn
2121

2222
from .io import ArrayConfiguration, SphericalGrid
23-
from .process import spatFT, iSpatFT
24-
from .sph import sph_harm, sph_harm_all, cart2sph, array_extrapolation, kr, sphankel2, dsphankel2
23+
from .process import iSpatFT, spatFT
24+
from .sph import array_extrapolation, cart2sph, dsphankel2, kr, sph_harm, sph_harm_all, sphankel2
2525

2626

2727
def whiteNoise(fftData, noiseLevel=80):
@@ -101,7 +101,7 @@ def lebedev(max_order=None, degree=None):
101101
Returns
102102
-------
103103
gridData : array_like
104-
Lebedev quadrature positions and weigths: [AZ, EL, W]
104+
Lebedev quadrature positions and weights: [AZ, EL, W]
105105
"""
106106
if max_order is None and not degree:
107107
raise ValueError('Either a maximum order or a degree have to be given.')
@@ -117,8 +117,7 @@ def lebedev(max_order=None, degree=None):
117117
raise ValueError('Maximum order can only be between 0 and 11.')
118118

119119
if degree not in allowed_degrees:
120-
raise ValueError('{} is an invalid quadrature degree. Choose one of the following: {}'.format(
121-
degree, allowed_degrees))
120+
raise ValueError(f'{degree} is an invalid quadrature degree. Choose one of the following: {allowed_degrees}')
122121

123122
from . import lebedev
124123
leb = lebedev.genGrid(degree)
@@ -336,8 +335,8 @@ def sampled_wave(order, fs, NFFT, array_configuration,
336335

337336
# TODO : Investigate if limit_order works as intended
338337
if max_order_fullspec > limit_order:
339-
print('Requested wave front needs a minimum order of {} but was limited to order {}'.format(
340-
max_order_fullspec, limit_order))
338+
print(f'Requested wave front needs a minimum order of {max_order_fullspec} but was limited to order '
339+
f'{limit_order}')
341340
Pnm = ideal_wave(min(max_order_fullspec, limit_order), fs, wave_azimuth, wave_colatitude, array_configuration,
342341
wavetype, distance, NFFT)
343342
Pnm_resampled = spatFT(iSpatFT(Pnm, gridData), gridData, order_max=order)

sound_field_analysis/io.py

Lines changed: 11 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
"""
2-
Input-Output functions"""
3-
1+
"""Input-Output functions"""
2+
import sys
43
from collections import namedtuple
54

65
import numpy as _np
@@ -48,10 +47,7 @@ def __new__(cls, array_radius, array_type, transducer_type, scatter_radius=None,
4847
return self
4948

5049
def __repr__(self):
51-
return 'ArrayConfiguration(\n' + ',\n'.join(
52-
' {0} = {1}'.format(name, repr(data).replace('\n', '\n '))
53-
for name, data in
54-
zip(['array_radius', 'array_type', 'transducer_type', 'scatter_radius', 'dual_radius'], self)) + ')'
50+
return utils.get_named_tuple__repr__(self)
5551

5652

5753
class TimeSignal(namedtuple('TimeSignal', 'signal fs delay')):
@@ -84,9 +80,7 @@ def __new__(cls, signal, fs, delay=None):
8480
return self
8581

8682
def __repr__(self):
87-
return 'TimeSignal(\n' + ',\n'.join(
88-
' {0} = {1}'.format(name, repr(data).replace('\n', '\n '))
89-
for name, data in zip(['signal', 'fs', 'delay'], self)) + ')'
83+
return utils.get_named_tuple__repr__(self)
9084

9185

9286
class SphericalGrid(namedtuple('SphericalGrid', 'azimuth colatitude radius weight')):
@@ -120,9 +114,7 @@ def __new__(cls, azimuth, colatitude, radius=None, weight=None):
120114
return self
121115

122116
def __repr__(self):
123-
return 'SphericalGrid(\n' + ',\n'.join(
124-
' {0} = {1}'.format(name, repr(data).replace('\n', '\n '))
125-
for name, data in zip(['azimuth', 'colatitude', 'radius', 'weight'], self)) + ')'
117+
return utils.get_named_tuple__repr__(self)
126118

127119

128120
class ArraySignal(namedtuple('ArraySignal', 'signal grid center_signal configuration temperature')):
@@ -154,9 +146,7 @@ def __new__(cls, signal, grid, center_signal=None, configuration=None, temperatu
154146
return self
155147

156148
def __repr__(self):
157-
return 'ArraySignal(\n' + ',\n'.join(
158-
' {0} = {1}'.format(name, repr(data).replace('\n', '\n '))
159-
for name, data in zip(['signal', 'grid', 'center_signal', 'configuration', 'temperature'], self)) + ')'
149+
return utils.get_named_tuple__repr__(self)
160150

161151

162152
class HrirSignal(namedtuple('HrirSignal', 'l r grid center_signal')):
@@ -188,9 +178,7 @@ def __new__(cls, l, r, grid, center_signal=None):
188178
return self
189179

190180
def __repr__(self):
191-
return 'HrirSignal(\n' + ',\n'.join(
192-
' {0} = {1}'.format(name, repr(data).replace('\n', '\n '))
193-
for name, data in zip(['l', 'r', 'grid', 'center_signal'], self)) + ')'
181+
return utils.get_named_tuple__repr__(self)
194182

195183

196184
def read_miro_struct(file_name, channel='irChOne', transducer_type='omni', scatter_radius=None,
@@ -236,7 +224,7 @@ def read_miro_struct(file_name, channel='irChOne', transducer_type='omni', scatt
236224
center_signal = TimeSignal(signal=_np.squeeze(current_data['irCenter']).T,
237225
fs=_np.squeeze(current_data['fs']))
238226
except KeyError:
239-
print('WARNING: Center signal not included in miro struct, use extended miro_to_struct.m!')
227+
print('WARNING: Center signal not included in miro struct, use extended miro_to_struct.m!', file=sys.stderr)
240228
center_signal = None
241229

242230
mic_grid = SphericalGrid(azimuth=_np.squeeze(current_data['azimuth']),
@@ -245,8 +233,8 @@ def read_miro_struct(file_name, channel='irChOne', transducer_type='omni', scatt
245233
weight=_np.squeeze(current_data['quadWeight']))
246234

247235
if (mic_grid.colatitude < 0).any():
248-
print("WARNING: The 'colatitude' data contains negative values, which is an indication that it is actually "
249-
"elevation")
236+
print('WARNING: The "colatitude" data contains negative values, which is an indication that it is actually '
237+
'elevation', file=sys.stderr)
250238

251239
if _np.squeeze(current_data['scatterer']):
252240
sphere_config = 'rigid'
@@ -383,7 +371,7 @@ def empty_time_signal(no_of_signals, signal_length):
383371
.air_temperature Average temperature in [C]
384372
"""
385373
return _np.rec.array(_np.zeros(no_of_signals,
386-
dtype=[('signal', str(signal_length) + 'f8'),
374+
dtype=[('signal', f'{signal_length}f8'),
387375
('fs', 'f8'),
388376
('azimuth', 'f8'),
389377
('colatitude', 'f8'),
@@ -447,8 +435,6 @@ def write_SSR_IRs(filename, time_data_l, time_data_r, wavformat='float32'):
447435
ValueError
448436
in case integer format should be exported and amplitude exceeds 1.0
449437
"""
450-
import sys
451-
452438
# make lower case and remove spaces
453439
wavformat = wavformat.lower().strip()
454440

sound_field_analysis/lebedev.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
"""Generate Lebedev grid and coefficients
1+
"""
2+
Generate Lebedev grid and coefficients
23
This module only exposes the function `lebGrid = lebedev.genGrid(degree)`.
34
45
lebGrid is a named tuple containing the coordinates .x, .y, .z and the weights .w
@@ -211,4 +212,4 @@ def genGrid(n):
211212
lebGrid.w = leb[:, 3]
212213
return lebGrid
213214
except KeyError:
214-
raise ValueError('No grid available for degree', n)
215+
raise ValueError(f'No grid available for degree {n}')

0 commit comments

Comments
 (0)