sofar 1.2.0__tar.gz → 1.2.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (120) hide show
  1. {sofar-1.2.0 → sofar-1.2.1}/CONTRIBUTING.rst +2 -4
  2. {sofar-1.2.0 → sofar-1.2.1}/HISTORY.rst +4 -0
  3. {sofar-1.2.0 → sofar-1.2.1}/PKG-INFO +55 -12
  4. {sofar-1.2.0 → sofar-1.2.1}/README.md +1 -0
  5. {sofar-1.2.0 → sofar-1.2.1}/docs/conf.py +4 -2
  6. sofar-1.2.1/docs/resources/conventions.py +162 -0
  7. sofar-1.2.1/pyproject.toml +154 -0
  8. sofar-1.2.1/setup.cfg +4 -0
  9. {sofar-1.2.0 → sofar-1.2.1}/sofar/__init__.py +2 -1
  10. {sofar-1.2.0 → sofar-1.2.1}/sofar/io.py +13 -17
  11. {sofar-1.2.0 → sofar-1.2.1}/sofar/sofa.py +53 -29
  12. sofar-1.2.1/sofar/sofa_conventions/write_upgrade_rules.py +139 -0
  13. sofar-1.2.1/sofar/sofa_conventions/write_verification_data.py +313 -0
  14. sofar-1.2.1/sofar/sofa_conventions/write_verification_rules.py +356 -0
  15. {sofar-1.2.0 → sofar-1.2.1}/sofar/sofastream.py +13 -8
  16. {sofar-1.2.0 → sofar-1.2.1}/sofar/update_conventions.py +19 -17
  17. {sofar-1.2.0 → sofar-1.2.1}/sofar/utils.py +4 -3
  18. {sofar-1.2.0 → sofar-1.2.1}/sofar.egg-info/PKG-INFO +55 -12
  19. {sofar-1.2.0 → sofar-1.2.1}/sofar.egg-info/SOURCES.txt +4 -4
  20. sofar-1.2.1/sofar.egg-info/requires.txt +30 -0
  21. sofar-1.2.1/sofar.egg-info/top_level.txt +5 -0
  22. {sofar-1.2.0 → sofar-1.2.1}/tests/test_deprecations.py +2 -2
  23. {sofar-1.2.0 → sofar-1.2.1}/tests/test_io.py +18 -17
  24. {sofar-1.2.0 → sofar-1.2.1}/tests/test_sofa.py +29 -30
  25. {sofar-1.2.0 → sofar-1.2.1}/tests/test_sofa_upgrade_conventions.py +1 -1
  26. {sofar-1.2.0 → sofar-1.2.1}/tests/test_sofa_verify.py +40 -39
  27. {sofar-1.2.0 → sofar-1.2.1}/tests/test_sofastream.py +12 -11
  28. {sofar-1.2.0 → sofar-1.2.1}/tests/test_utils.py +5 -6
  29. sofar-1.2.0/AUTHORS.rst +0 -15
  30. sofar-1.2.0/pyproject.toml +0 -13
  31. sofar-1.2.0/setup.cfg +0 -23
  32. sofar-1.2.0/setup.py +0 -76
  33. sofar-1.2.0/sofar.egg-info/not-zip-safe +0 -1
  34. sofar-1.2.0/sofar.egg-info/requires.txt +0 -5
  35. sofar-1.2.0/sofar.egg-info/top_level.txt +0 -2
  36. {sofar-1.2.0 → sofar-1.2.1}/LICENSE +0 -0
  37. {sofar-1.2.0 → sofar-1.2.1}/MANIFEST.in +0 -0
  38. {sofar-1.2.0 → sofar-1.2.1}/docs/Makefile +0 -0
  39. {sofar-1.2.0 → sofar-1.2.1}/docs/api_reference.rst +0 -0
  40. {sofar-1.2.0 → sofar-1.2.1}/docs/contributing.rst +0 -0
  41. {sofar-1.2.0 → sofar-1.2.1}/docs/history.rst +0 -0
  42. {sofar-1.2.0 → sofar-1.2.1}/docs/index.rst +0 -0
  43. {sofar-1.2.0 → sofar-1.2.1}/docs/make.bat +0 -0
  44. {sofar-1.2.0 → sofar-1.2.1}/docs/readme.rst +0 -0
  45. {sofar-1.2.0 → sofar-1.2.1}/docs/resources/working_with_sofa_HRIR_lateral.png +0 -0
  46. {sofar-1.2.0 → sofar-1.2.1}/docs/resources/working_with_sofa_source_horizontal.png +0 -0
  47. {sofar-1.2.0 → sofar-1.2.1}/docs/resources/working_with_sofa_source_lateral.png +0 -0
  48. {sofar-1.2.0 → sofar-1.2.1}/docs/sofar.rst +0 -0
  49. {sofar-1.2.0 → sofar-1.2.1}/sofar/sofa_conventions/VERSION +0 -0
  50. {sofar-1.2.0 → sofar-1.2.1}/sofar/sofa_conventions/conventions/AnnotatedEmitterAudio_0.2.csv +0 -0
  51. {sofar-1.2.0 → sofar-1.2.1}/sofar/sofa_conventions/conventions/AnnotatedEmitterAudio_0.2.json +0 -0
  52. {sofar-1.2.0 → sofar-1.2.1}/sofar/sofa_conventions/conventions/AnnotatedReceiverAudio_0.2.csv +0 -0
  53. {sofar-1.2.0 → sofar-1.2.1}/sofar/sofa_conventions/conventions/AnnotatedReceiverAudio_0.2.json +0 -0
  54. {sofar-1.2.0 → sofar-1.2.1}/sofar/sofa_conventions/conventions/FreeFieldDirectivityTF_1.1.csv +0 -0
  55. {sofar-1.2.0 → sofar-1.2.1}/sofar/sofa_conventions/conventions/FreeFieldDirectivityTF_1.1.json +0 -0
  56. {sofar-1.2.0 → sofar-1.2.1}/sofar/sofa_conventions/conventions/FreeFieldHRIR_1.0.csv +0 -0
  57. {sofar-1.2.0 → sofar-1.2.1}/sofar/sofa_conventions/conventions/FreeFieldHRIR_1.0.json +0 -0
  58. {sofar-1.2.0 → sofar-1.2.1}/sofar/sofa_conventions/conventions/FreeFieldHRTF_1.0.csv +0 -0
  59. {sofar-1.2.0 → sofar-1.2.1}/sofar/sofa_conventions/conventions/FreeFieldHRTF_1.0.json +0 -0
  60. {sofar-1.2.0 → sofar-1.2.1}/sofar/sofa_conventions/conventions/GeneralFIR-E_2.0.csv +0 -0
  61. {sofar-1.2.0 → sofar-1.2.1}/sofar/sofa_conventions/conventions/GeneralFIR-E_2.0.json +0 -0
  62. {sofar-1.2.0 → sofar-1.2.1}/sofar/sofa_conventions/conventions/GeneralFIR_1.0.csv +0 -0
  63. {sofar-1.2.0 → sofar-1.2.1}/sofar/sofa_conventions/conventions/GeneralFIR_1.0.json +0 -0
  64. {sofar-1.2.0 → sofar-1.2.1}/sofar/sofa_conventions/conventions/GeneralSOS_1.0.csv +0 -0
  65. {sofar-1.2.0 → sofar-1.2.1}/sofar/sofa_conventions/conventions/GeneralSOS_1.0.json +0 -0
  66. {sofar-1.2.0 → sofar-1.2.1}/sofar/sofa_conventions/conventions/GeneralTF-E_1.0.csv +0 -0
  67. {sofar-1.2.0 → sofar-1.2.1}/sofar/sofa_conventions/conventions/GeneralTF-E_1.0.json +0 -0
  68. {sofar-1.2.0 → sofar-1.2.1}/sofar/sofa_conventions/conventions/GeneralTF_1.0.csv +0 -0
  69. {sofar-1.2.0 → sofar-1.2.1}/sofar/sofa_conventions/conventions/GeneralTF_1.0.json +0 -0
  70. {sofar-1.2.0 → sofar-1.2.1}/sofar/sofa_conventions/conventions/GeneralTF_2.0.csv +0 -0
  71. {sofar-1.2.0 → sofar-1.2.1}/sofar/sofa_conventions/conventions/GeneralTF_2.0.json +0 -0
  72. {sofar-1.2.0 → sofar-1.2.1}/sofar/sofa_conventions/conventions/SimpleFreeFieldHRIR_1.0.csv +0 -0
  73. {sofar-1.2.0 → sofar-1.2.1}/sofar/sofa_conventions/conventions/SimpleFreeFieldHRIR_1.0.json +0 -0
  74. {sofar-1.2.0 → sofar-1.2.1}/sofar/sofa_conventions/conventions/SimpleFreeFieldHRSOS_1.0.csv +0 -0
  75. {sofar-1.2.0 → sofar-1.2.1}/sofar/sofa_conventions/conventions/SimpleFreeFieldHRSOS_1.0.json +0 -0
  76. {sofar-1.2.0 → sofar-1.2.1}/sofar/sofa_conventions/conventions/SimpleFreeFieldHRTF_1.0.csv +0 -0
  77. {sofar-1.2.0 → sofar-1.2.1}/sofar/sofa_conventions/conventions/SimpleFreeFieldHRTF_1.0.json +0 -0
  78. {sofar-1.2.0 → sofar-1.2.1}/sofar/sofa_conventions/conventions/SimpleFreeFieldSOS_1.0.csv +0 -0
  79. {sofar-1.2.0 → sofar-1.2.1}/sofar/sofa_conventions/conventions/SimpleFreeFieldSOS_1.0.json +0 -0
  80. {sofar-1.2.0 → sofar-1.2.1}/sofar/sofa_conventions/conventions/SimpleHeadphoneIR_1.0.csv +0 -0
  81. {sofar-1.2.0 → sofar-1.2.1}/sofar/sofa_conventions/conventions/SimpleHeadphoneIR_1.0.json +0 -0
  82. {sofar-1.2.0 → sofar-1.2.1}/sofar/sofa_conventions/conventions/SingleRoomMIMOSRIR_1.0.csv +0 -0
  83. {sofar-1.2.0 → sofar-1.2.1}/sofar/sofa_conventions/conventions/SingleRoomMIMOSRIR_1.0.json +0 -0
  84. {sofar-1.2.0 → sofar-1.2.1}/sofar/sofa_conventions/conventions/SingleRoomSRIR_1.0.csv +0 -0
  85. {sofar-1.2.0 → sofar-1.2.1}/sofar/sofa_conventions/conventions/SingleRoomSRIR_1.0.json +0 -0
  86. {sofar-1.2.0 → sofar-1.2.1}/sofar/sofa_conventions/conventions/deprecated/AnnotatedEmitterAudio_0.1.csv +0 -0
  87. {sofar-1.2.0 → sofar-1.2.1}/sofar/sofa_conventions/conventions/deprecated/AnnotatedEmitterAudio_0.1.json +0 -0
  88. {sofar-1.2.0 → sofar-1.2.1}/sofar/sofa_conventions/conventions/deprecated/AnnotatedReceiverAudio_0.1.csv +0 -0
  89. {sofar-1.2.0 → sofar-1.2.1}/sofar/sofa_conventions/conventions/deprecated/AnnotatedReceiverAudio_0.1.json +0 -0
  90. {sofar-1.2.0 → sofar-1.2.1}/sofar/sofa_conventions/conventions/deprecated/FreeFieldDirectivityTF_1.0.csv +0 -0
  91. {sofar-1.2.0 → sofar-1.2.1}/sofar/sofa_conventions/conventions/deprecated/FreeFieldDirectivityTF_1.0.json +0 -0
  92. {sofar-1.2.0 → sofar-1.2.1}/sofar/sofa_conventions/conventions/deprecated/GeneralFIRE_1.0.csv +0 -0
  93. {sofar-1.2.0 → sofar-1.2.1}/sofar/sofa_conventions/conventions/deprecated/GeneralFIRE_1.0.json +0 -0
  94. {sofar-1.2.0 → sofar-1.2.1}/sofar/sofa_conventions/conventions/deprecated/MultiSpeakerBRIR_0.3.csv +0 -0
  95. {sofar-1.2.0 → sofar-1.2.1}/sofar/sofa_conventions/conventions/deprecated/MultiSpeakerBRIR_0.3.json +0 -0
  96. {sofar-1.2.0 → sofar-1.2.1}/sofar/sofa_conventions/conventions/deprecated/SimpleFreeFieldHRIR_0.4.csv +0 -0
  97. {sofar-1.2.0 → sofar-1.2.1}/sofar/sofa_conventions/conventions/deprecated/SimpleFreeFieldHRIR_0.4.json +0 -0
  98. {sofar-1.2.0 → sofar-1.2.1}/sofar/sofa_conventions/conventions/deprecated/SimpleFreeFieldTF_0.4.csv +0 -0
  99. {sofar-1.2.0 → sofar-1.2.1}/sofar/sofa_conventions/conventions/deprecated/SimpleFreeFieldTF_0.4.json +0 -0
  100. {sofar-1.2.0 → sofar-1.2.1}/sofar/sofa_conventions/conventions/deprecated/SimpleFreeFieldTF_1.0.csv +0 -0
  101. {sofar-1.2.0 → sofar-1.2.1}/sofar/sofa_conventions/conventions/deprecated/SimpleFreeFieldTF_1.0.json +0 -0
  102. {sofar-1.2.0 → sofar-1.2.1}/sofar/sofa_conventions/conventions/deprecated/SimpleHeadphoneIR_0.1.csv +0 -0
  103. {sofar-1.2.0 → sofar-1.2.1}/sofar/sofa_conventions/conventions/deprecated/SimpleHeadphoneIR_0.1.json +0 -0
  104. {sofar-1.2.0 → sofar-1.2.1}/sofar/sofa_conventions/conventions/deprecated/SimpleHeadphoneIR_0.2.csv +0 -0
  105. {sofar-1.2.0 → sofar-1.2.1}/sofar/sofa_conventions/conventions/deprecated/SimpleHeadphoneIR_0.2.json +0 -0
  106. {sofar-1.2.0 → sofar-1.2.1}/sofar/sofa_conventions/conventions/deprecated/SingleRoomDRIR_0.2.csv +0 -0
  107. {sofar-1.2.0 → sofar-1.2.1}/sofar/sofa_conventions/conventions/deprecated/SingleRoomDRIR_0.2.json +0 -0
  108. {sofar-1.2.0 → sofar-1.2.1}/sofar/sofa_conventions/conventions/deprecated/SingleRoomDRIR_0.3.csv +0 -0
  109. {sofar-1.2.0 → sofar-1.2.1}/sofar/sofa_conventions/conventions/deprecated/SingleRoomDRIR_0.3.json +0 -0
  110. {sofar-1.2.0 → sofar-1.2.1}/sofar/sofa_conventions/conventions/deprecated/SingleTrackedAudio_0.1.csv +0 -0
  111. {sofar-1.2.0 → sofar-1.2.1}/sofar/sofa_conventions/conventions/deprecated/SingleTrackedAudio_0.1.json +0 -0
  112. {sofar-1.2.0 → sofar-1.2.1}/sofar/sofa_conventions/conventions/deprecated/SingleTrackedAudio_0.2.csv +0 -0
  113. {sofar-1.2.0 → sofar-1.2.1}/sofar/sofa_conventions/conventions/deprecated/SingleTrackedAudio_0.2.json +0 -0
  114. {sofar-1.2.0 → sofar-1.2.1}/sofar/sofa_conventions/rules/deprecations.json +0 -0
  115. {sofar-1.2.0 → sofar-1.2.1}/sofar/sofa_conventions/rules/rules.json +0 -0
  116. {sofar-1.2.0 → sofar-1.2.1}/sofar/sofa_conventions/rules/unit_aliases.json +0 -0
  117. {sofar-1.2.0 → sofar-1.2.1}/sofar/sofa_conventions/rules/upgrade.json +0 -0
  118. {sofar-1.2.0 → sofar-1.2.1}/sofar.egg-info/dependency_links.txt +0 -0
  119. {sofar-1.2.0 → sofar-1.2.1}/tests/__init__.py +0 -0
  120. {sofar-1.2.0 → sofar-1.2.1}/tests/conftest.py +0 -0
@@ -45,14 +45,12 @@ Ready to contribute? Here's how to set up `sofar` for local development using th
45
45
  3. Note that some graphical Git interfaces can not do the recursive clone. If the folder sofar/sofa_conventions is empty try::
46
46
 
47
47
  $ git submodule update --init
48
-
48
+
49
49
  4. Install your local copy into a virtualenv. Assuming you have Anaconda or Miniconda installed, this is how you set up your fork for local development::
50
50
 
51
51
  $ conda create --name sofar python
52
52
  $ conda activate sofar
53
- $ conda install pip
54
- $ pip install -e .
55
- $ pip install -r requirements_dev.txt
53
+ $ pip install -e ".[dev]"
56
54
 
57
55
  5. Create a branch for local development. Indicate the intention of your branch in its respective name (i.e. `feature/branch-name` or `bugfix/branch-name`)::
58
56
 
@@ -2,6 +2,10 @@
2
2
  History
3
3
  =======
4
4
 
5
+ 1.2.1 (2024-12-12)
6
+ ------------------
7
+ * Deployment: Move from setup.py to pyproject.toml (PR #114, #115)
8
+
5
9
  1.2.0 (2024-08-29)
6
10
  ------------------
7
11
  * Feature: Introduce `SofaStream` class for reading parts of large Sofa files without reading the entire file (PR #90, 97)
@@ -1,16 +1,38 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: sofar
3
- Version: 1.2.0
4
- Summary: Maybe the most complete python package for SOFA files so far
5
- Home-page: https://pyfar.org/
6
- Download-URL: https://pypi.org/project/sofar/
7
- Author: The pyfar developers
8
- Author-email: info@pyfar.org
9
- License: MIT license
10
- Project-URL: Bug Tracker, https://github.com/pyfar/sofar/issues
3
+ Version: 1.2.1
4
+ Summary: Maybe the most complete python package for SOFA files so far.
5
+ Author-email: The pyfar developers <info@pyfar.org>
6
+ License: MIT License
7
+
8
+ Copyright (c) 2021, The pyfar developers
9
+
10
+ Permission is hereby granted, free of charge, to any person obtaining a copy
11
+ of this software and associated documentation files (the "Software"), to deal
12
+ in the Software without restriction, including without limitation the rights
13
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
+ copies of the Software, and to permit persons to whom the Software is
15
+ furnished to do so, subject to the following conditions:
16
+
17
+ The above copyright notice and this permission notice shall be included in all
18
+ copies or substantial portions of the Software.
19
+
20
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
+ SOFTWARE.
27
+
28
+
29
+ Project-URL: Tracker, https://github.com/pyfar/sofar/issues
11
30
  Project-URL: Documentation, https://sofar.readthedocs.io/
12
- Project-URL: Source Code, https://github.com/pyfar/sofar
13
- Keywords: sofar
31
+ Project-URL: Download, https://pypi.org/project/sofar/
32
+ Project-URL: Homepage, https://pyfar.org/
33
+ Project-URL: Source, https://github.com/pyfar/sofar
34
+ Project-URL: Changelog, https://github.com/pyfar/sofar/blob/main/HISTORY.rst
35
+ Keywords: acoustics,pyfar
14
36
  Classifier: Development Status :: 4 - Beta
15
37
  Classifier: Intended Audience :: Science/Research
16
38
  Classifier: License :: OSI Approved :: MIT License
@@ -24,12 +46,32 @@ Classifier: Programming Language :: Python :: 3.12
24
46
  Requires-Python: >=3.8
25
47
  Description-Content-Type: text/markdown
26
48
  License-File: LICENSE
27
- License-File: AUTHORS.rst
28
49
  Requires-Dist: netCDF4
29
50
  Requires-Dist: numpy>=1.14.0
30
51
  Requires-Dist: beautifulsoup4
31
52
  Requires-Dist: requests
32
- Requires-Dist: packaging
53
+ Provides-Extra: deploy
54
+ Requires-Dist: twine; extra == "deploy"
55
+ Requires-Dist: wheel; extra == "deploy"
56
+ Requires-Dist: build; extra == "deploy"
57
+ Requires-Dist: setuptools; extra == "deploy"
58
+ Requires-Dist: bump-my-version; extra == "deploy"
59
+ Provides-Extra: tests
60
+ Requires-Dist: pytest; extra == "tests"
61
+ Requires-Dist: pytest-cov; extra == "tests"
62
+ Requires-Dist: watchdog; extra == "tests"
63
+ Requires-Dist: ruff==0.8.2; extra == "tests"
64
+ Requires-Dist: coverage; extra == "tests"
65
+ Provides-Extra: docs
66
+ Requires-Dist: sphinx; extra == "docs"
67
+ Requires-Dist: autodocsumm>=0.2.14; extra == "docs"
68
+ Requires-Dist: pydata-sphinx-theme; extra == "docs"
69
+ Requires-Dist: sphinx_mdinclude; extra == "docs"
70
+ Requires-Dist: sphinx-design; extra == "docs"
71
+ Requires-Dist: sphinx-favicon; extra == "docs"
72
+ Requires-Dist: sphinx-reredirects; extra == "docs"
73
+ Provides-Extra: dev
74
+ Requires-Dist: sofar[deploy,docs,tests]; extra == "dev"
33
75
 
34
76
  <h1 align="center">
35
77
  <img src="https://github.com/pyfar/gallery/raw/main/docs/resources/logos/pyfar_logos_fixed_size_sofar.png" width="300">
@@ -38,6 +80,7 @@ Requires-Dist: packaging
38
80
  [![PyPI version](https://badge.fury.io/py/sofar.svg)](https://badge.fury.io/py/sofar)
39
81
  [![Documentation Status](https://readthedocs.org/projects/sofar/badge/?version=latest)](https://sofar.readthedocs.io/en/latest/?badge=latest)
40
82
  [![CircleCI](https://circleci.com/gh/pyfar/sofar.svg?style=shield)](https://circleci.com/gh/pyfar/sofar)
83
+ [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/pyfar/gallery/main?labpath=docs/gallery/interactive/sofar_introduction.ipynb)
41
84
 
42
85
  Sofar is maybe the most complete Python package for the SOFA file format so
43
86
  far. SOFA files store spatially distributed acoustic data such as impulse
@@ -5,6 +5,7 @@
5
5
  [![PyPI version](https://badge.fury.io/py/sofar.svg)](https://badge.fury.io/py/sofar)
6
6
  [![Documentation Status](https://readthedocs.org/projects/sofar/badge/?version=latest)](https://sofar.readthedocs.io/en/latest/?badge=latest)
7
7
  [![CircleCI](https://circleci.com/gh/pyfar/sofar.svg?style=shield)](https://circleci.com/gh/pyfar/sofar)
8
+ [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/pyfar/gallery/main?labpath=docs/gallery/interactive/sofar_introduction.ipynb)
8
9
 
9
10
  Sofar is maybe the most complete Python package for the SOFA file format so
10
11
  far. SOFA files store spatially distributed acoustic data such as impulse
@@ -12,8 +12,8 @@ import urllib3
12
12
  import shutil
13
13
  sys.path.insert(0, os.path.abspath('..'))
14
14
 
15
- import sofar # noqa
16
- import resources.conventions # noqa: build conventions for documentation
15
+ import sofar
16
+ import resources.conventions
17
17
 
18
18
  # -- General configuration ---------------------------------------------------
19
19
  # https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
@@ -130,6 +130,8 @@ html_theme_options = {
130
130
  "show_toc_level": 3, # Show all subsections of notebooks
131
131
  "secondary_sidebar_items": ["page-toc"], # Omit 'show source' link that that shows notebook in json format
132
132
  "navigation_with_keys": True,
133
+ # Configure navigation depth for section navigation
134
+ "navigation_depth": 1,
133
135
  }
134
136
 
135
137
  html_context = {
@@ -0,0 +1,162 @@
1
+ import os
2
+ import sys
3
+ import json
4
+ sys.path.insert(0, os.path.abspath(os.path.join('..', '..')))
5
+
6
+ import sofar as sf
7
+
8
+ base_dir = os.path.dirname(__file__)
9
+
10
+ # get conventions (paths, names, version) and upgrade rules -------------------
11
+ paths = sf.utils._get_conventions('path')
12
+ names_versions = sf.utils._get_conventions('name_version')
13
+
14
+ # using Sofa()._verification_rules() does not work on readthedocs
15
+ upgrade_rules = os.path.join(
16
+ os.path.dirname(paths[0]), '..', 'rules', 'upgrade.json')
17
+ with open(upgrade_rules) as file:
18
+ upgrade_rules = json.load(file)
19
+
20
+ deprecation_rules = os.path.join(
21
+ os.path.dirname(paths[0]), '..', 'rules', 'deprecations.json')
22
+ with open(deprecation_rules) as file:
23
+ deprecation_rules = json.load(file)
24
+
25
+ # write general information ---------------------------------------------------
26
+ docs = (
27
+ '.. _conventions_introduction:\n\n'
28
+ 'SOFA Conventions\n'
29
+ '================\n\n'
30
+ 'SOFA conventions specify what data and metadata must be stored in a SOFA '
31
+ 'file. Different conventions can be used to store different types of data,'
32
+ 'e.g., head-related impulse responses or musical instrument directivities.'
33
+ 'It is advised to always use the conventions that is most specific for the'
34
+ 'data.\n\n'
35
+ 'In the following, SOFA conventions are described in tables with the '
36
+ 'information\n\n'
37
+ '* **Name:** The Name of the data. The prefix *GLOBAL* denotes global '
38
+ 'attribute, i.e., attributes that pertain the entire data set. Underscores'
39
+ ' denote attributes that are data specific. E.g., *SourcePosition_Units* '
40
+ 'denotes the *Units* of the data *SourcePosition*.\n'
41
+ '* **Type:** The Type of the data.\n\n'
42
+ ' * **Attribute:** A verbose description given by a string\n'
43
+ ' * **Double:** A numeric array of data\n'
44
+ ' * **String:** A string array of data\n\n'
45
+ '* **Default:** The default value\n'
46
+ '* **Dimensions:** The dimensions of the data. Lower case letters denote '
47
+ 'the data that sets the dimension.\n\n'
48
+ ' * **E:** Number of emitters\n'
49
+ ' * **R:** Number of receivers\n'
50
+ ' * **M:** Number of measurements\n'
51
+ ' * **N:** Number of samples or frequency bins of the data\n'
52
+ ' * **C:** Number of coordinates (always 3)\n'
53
+ ' * **I:** Unity dimensions (always 1)\n'
54
+ ' * **S:** Lengths of the longest string contained in the data '
55
+ '(detected automatically)\n\n'
56
+ '* **Flags:**\n\n'
57
+ ' * **r:** read only data. Data can be written if flag is missing.\n'
58
+ ' * **m:** mandatory data. Data is optional if flag is missing\n\n')
59
+
60
+ # write table of content ------------------------------------------------------
61
+ docs += '.. _conventions:\n\nConventions\n-----------\n\n'
62
+ for path, name_version in zip(paths, names_versions):
63
+ name, version = name_version
64
+
65
+ label = f'{name} v{version}'
66
+ if 'deprecated' in path:
67
+ label += ' (deprecated)'
68
+ reference = f'{name}_{version}'
69
+
70
+ docs += f'* :ref:`{label} <{reference}>`\n'
71
+
72
+ # write conventions -----------------------------------------------------------
73
+ docs += '\nCurrent\n-------\n\n'
74
+
75
+ # loop conventions
76
+ deprecated = False
77
+ for path, name_version in zip(paths, names_versions):
78
+ name, version = name_version
79
+
80
+ # read convention from json file
81
+ with open(path, 'r') as file:
82
+ convention = json.load(file)
83
+
84
+ # write section title
85
+ if 'deprecated' in path and not deprecated:
86
+ docs += 'Deprecated\n----------\n\n'
87
+ deprecated = True
88
+
89
+ # write convention name, version
90
+ docs += f'.. _{name}_{version}:\n\n'
91
+ docs += f'**{name} v{version}**\n\n'
92
+
93
+ # name new convention if current convention is deprecated
94
+ if deprecated:
95
+ # upgrade rules give best feedback
96
+ if name in upgrade_rules:
97
+ for upgrade in upgrade_rules[name]['from_to']:
98
+ if version in upgrade[0]:
99
+ upgrade_to = upgrade[1]
100
+ references = [f':ref:`{u} <{u}>`' for u in upgrade_to]
101
+ ':ref:`{label} <{reference}>`'
102
+ docs += ('This convention is deprecated. '
103
+ f'Use {", ".join(references)} instead.\n\n')
104
+ # deprecations are used if no upgrade rules are available
105
+ elif name in deprecation_rules['GLOBAL:SOFAConventions']:
106
+ docs += ("This convention is deprecated. Use "
107
+ f"{deprecation_rules['GLOBAL:SOFAConventions'][name]} "
108
+ "instead.\n\n")
109
+
110
+ # name purpose of the convention
111
+ docs += f'{convention["GLOBAL:SOFAConventions"]["comment"]}\n\n'
112
+
113
+ # write header
114
+ docs += (
115
+ '.. list-table::\n'
116
+ ' :widths: 20 50 25 30 100\n'
117
+ ' :header-rows: 1\n\n'
118
+ ' * - Name (Type)\n'
119
+ ' - Default\n'
120
+ ' - Dim.\n'
121
+ ' - Flags\n'
122
+ ' - Comment\n')
123
+
124
+ # loop entries
125
+ for key, value in convention.items():
126
+
127
+ if value["dimensions"] is None:
128
+ dimensions = ""
129
+ else:
130
+ dimensions = value["dimensions"]
131
+
132
+ if value["flags"] is None:
133
+ flags = ""
134
+ elif len(value["flags"]) > 1:
135
+ flags = f'{value["flags"][0]}, {value["flags"][1]}'
136
+ else:
137
+ flags = value["flags"]
138
+
139
+ if key == "GLOBAL:SOFAConventions":
140
+ value["comment"] = ""
141
+
142
+ if value["type"] == 'attribute':
143
+ type_str = 'attr.'
144
+ elif value["type"] == 'double':
145
+ type_str = 'doub.'
146
+ else:
147
+ type_str = 'str.'
148
+
149
+ docs += (
150
+ f' * - {key.replace(":", "_").replace(".", "_")} '
151
+ f'(*{value["type"]}*)\n'
152
+ f' - {value["default"]}\n'
153
+ f' - {dimensions}\n'
154
+ f' - {flags}\n'
155
+ f' - {value["comment"]}\n')
156
+
157
+ docs += '\n:ref:`back to top <conventions>`\n\n'
158
+
159
+ # write docs to rst file ------------------------------------------------------
160
+ docs_file = os.path.join(base_dir, 'conventions.rst')
161
+ with open(docs_file, 'w') as file:
162
+ file.writelines(docs)
@@ -0,0 +1,154 @@
1
+ [project]
2
+ name = "sofar"
3
+ version = "1.2.1"
4
+ description = "Maybe the most complete python package for SOFA files so far."
5
+ readme = "README.md"
6
+ license = {file = "LICENSE"}
7
+ requires-python = ">=3.8"
8
+ authors = [
9
+ { name = "The pyfar developers", email = "info@pyfar.org" },
10
+ ]
11
+ keywords = [
12
+ "acoustics",
13
+ "pyfar",
14
+ ]
15
+ classifiers = [
16
+ "Development Status :: 4 - Beta",
17
+ "Intended Audience :: Science/Research",
18
+ "License :: OSI Approved :: MIT License",
19
+ "Natural Language :: English",
20
+ "Programming Language :: Python :: 3",
21
+ "Programming Language :: Python :: 3.8",
22
+ "Programming Language :: Python :: 3.9",
23
+ "Programming Language :: Python :: 3.10",
24
+ "Programming Language :: Python :: 3.11",
25
+ "Programming Language :: Python :: 3.12",
26
+ ]
27
+ dependencies = [
28
+ 'netCDF4',
29
+ 'numpy>=1.14.0',
30
+ 'beautifulsoup4',
31
+ 'requests',
32
+ ]
33
+
34
+ [project.optional-dependencies]
35
+ deploy = [
36
+ "twine",
37
+ "wheel",
38
+ "build",
39
+ "setuptools",
40
+ "bump-my-version",
41
+ ]
42
+ tests = [
43
+ "pytest",
44
+ "pytest-cov",
45
+ "watchdog",
46
+ "ruff==0.8.2",
47
+ "coverage",
48
+ ]
49
+ docs = [
50
+ "sphinx",
51
+ "autodocsumm>=0.2.14",
52
+ "pydata-sphinx-theme",
53
+ "sphinx_mdinclude",
54
+ "sphinx-design",
55
+ "sphinx-favicon",
56
+ "sphinx-reredirects",
57
+ ]
58
+ dev = ["sofar[deploy,tests,docs]"]
59
+
60
+ [project.urls]
61
+ Tracker = "https://github.com/pyfar/sofar/issues"
62
+ Documentation = "https://sofar.readthedocs.io/"
63
+ Download = "https://pypi.org/project/sofar/"
64
+ Homepage = "https://pyfar.org/"
65
+ Source = "https://github.com/pyfar/sofar"
66
+ Changelog = "https://github.com/pyfar/sofar/blob/main/HISTORY.rst"
67
+
68
+ [build-system]
69
+ requires = ["setuptools>=61.0", "wheel"]
70
+ build-backend = "setuptools.build_meta"
71
+
72
+ [tool.setuptools.packages]
73
+ find = {} # Scan the project directory with the default parameters
74
+
75
+
76
+ [tool.ruff]
77
+ exclude = [
78
+ ".git",
79
+ "docs",
80
+ ]
81
+ line-length = 79
82
+ lint.ignore = [
83
+ "D200", # One-line docstring should fit on one line with quotes
84
+ "D202", # No blank lines allowed after function docstring
85
+ "D205", # 1 blank line required between summary line and description
86
+ "D401", # First line should be in imperative mood
87
+ "D404", # First word of the docstring should not be "This"
88
+ "B006", # Do not use mutable data structures for argument defaults
89
+ "B008", # Do not perform calls in argument defaults
90
+ "PT018", # Assertion should be broken down into multiple parts
91
+ "PT019", # Fixture `_` without value is injected as parameter
92
+ ]
93
+ lint.select = [
94
+ "B", # bugbear extension
95
+ "ARG", # Remove unused function/method arguments
96
+ "C4", # Check for common security issues
97
+ "E", # PEP8 errors
98
+ "F", # Pyflakes
99
+ "W", # PEP8 warnings
100
+ "D", # Docstring guidelines
101
+ "NPY", # Check all numpy related deprecations
102
+ "D417", # Missing argument descriptions in the docstring
103
+ "PT", # Pytest style
104
+ "A", # Avoid builtin function and type shadowing
105
+ "ERA", # No commented out code
106
+ "NPY", # Check all numpy related deprecations
107
+ "COM", # trailing comma rules
108
+ "I002", # missing required import
109
+ "TID252", # Use absolute over relative imports
110
+ "FIX", # Code should not contain FIXME, TODO, etc
111
+ ]
112
+
113
+ # Ignore missing docstrings in tests
114
+ [tool.ruff.lint.per-file-ignores]
115
+ "tests/*" = [
116
+ "D100",
117
+ "D101",
118
+ "D103",
119
+ "D104",
120
+ ]
121
+
122
+ [tool.ruff.lint.pydocstyle]
123
+ convention = "numpy"
124
+
125
+ [tool.bumpversion]
126
+ current_version = "1.2.1"
127
+ parse = "(?P<major>\\d+)\\.(?P<minor>\\d+)\\.(?P<patch>\\d+)"
128
+ serialize = ["{major}.{minor}.{patch}"]
129
+ search = "{current_version}"
130
+ replace = "{new_version}"
131
+ regex = true
132
+ ignore_missing_version = false
133
+ ignore_missing_files = false
134
+ tag = true
135
+ sign_tags = false
136
+ tag_name = "v{new_version}"
137
+ tag_message = "Bump version: {current_version} → {new_version}"
138
+ allow_dirty = false
139
+ commit = true
140
+ message = "Bump version: {current_version} → {new_version}"
141
+ commit_args = ""
142
+ setup_hooks = []
143
+ pre_commit_hooks = []
144
+ post_commit_hooks = []
145
+
146
+ [[tool.bumpversion.files]]
147
+ filename = "pyproject.toml"
148
+ search = '\nversion = "{current_version}"'
149
+ replace = '\nversion = "{new_version}"'
150
+
151
+ [[tool.bumpversion.files]]
152
+ filename = "sofar/__init__.py"
153
+ search = "__version__ = '{current_version}'"
154
+ replace = "__version__ = '{new_version}'"
sofar-1.2.1/setup.cfg ADDED
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -1,7 +1,8 @@
1
+ """Main init that determines how the sofar package is structured."""
1
2
  # -*- coding: utf-8 -*-
2
3
  __author__ = """The pyfar developers"""
3
4
  __email__ = 'info@pyfar.org'
4
- __version__ = '1.2.0'
5
+ __version__ = '1.2.1'
5
6
 
6
7
  from .sofa import Sofa
7
8
 
@@ -1,3 +1,4 @@
1
+ """Module for reading and writing Sofa files with sofar."""
1
2
  import contextlib
2
3
  import os
3
4
  import numpy as np
@@ -41,7 +42,6 @@ def read_sofa(filename, verify='auto', verbose=True):
41
42
 
42
43
  Notes
43
44
  -----
44
-
45
45
  1. Missing dimensions are appended when writing the SOFA object to disk.
46
46
  E.g., if ``sofa.Data_IR`` is of shape (1, 2) it is written as an array
47
47
  of shape (1, 2, 1) because the SOFA standard AES69 defines it as a
@@ -92,7 +92,6 @@ def read_sofa_as_netcdf(filename):
92
92
 
93
93
  Notes
94
94
  -----
95
-
96
95
  1. Missing dimensions are appended when writing the SOFA object to disk.
97
96
  E.g., if ``sofa.Data_IR`` is of shape (1, 2) it is written as an array
98
97
  of shape (1, 2, 1) because the SOFA standard AES69 defines it as a
@@ -129,8 +128,8 @@ def _read_netcdf(filename, verify, verbose, mode):
129
128
 
130
129
  if mode == "sofa":
131
130
  # get convention name and version
132
- convention = getattr(file, "SOFAConventions")
133
- version = getattr(file, "SOFAConventionsVersion")
131
+ convention = file.SOFAConventions
132
+ version = file.SOFAConventionsVersion
134
133
 
135
134
  # check if convention and version exist
136
135
  _verify_convention_and_version(version, convention)
@@ -213,11 +212,11 @@ def _read_netcdf(filename, verify, verbose, mode):
213
212
  if verify:
214
213
  try:
215
214
  sofa.verify(mode="read")
216
- except: # noqa (No error handling - just improved verbosity)
215
+ except: # noqa: E722
217
216
  raise ValueError((
218
217
  "The SOFA object could not be verified, maybe due to erroneous"
219
218
  " data. Call sofa=sofar.read_sofa(filename, verify=False) and "
220
- "then sofa.verify() to get more information"))
219
+ "then sofa.verify() to get more information")) from None
221
220
 
222
221
  return sofa
223
222
 
@@ -240,7 +239,6 @@ def write_sofa(filename: str, sofa: sf.Sofa, compression=4):
240
239
 
241
240
  Notes
242
241
  -----
243
-
244
242
  1. Missing dimensions are appended when writing the SOFA object to disk.
245
243
  E.g., if ``sofa.Data_IR`` is of shape (1, 2) it is written as an array
246
244
  of shape (1, 2, 1) because the SOFA standard AES69 defines it as a
@@ -281,7 +279,7 @@ def _write_sofa(filename: str, sofa: sf.Sofa, compression=4, verify=True):
281
279
  "Writing SOFA object with outdated Convention "
282
280
  f"version {current}. It is recommend to upgrade "
283
281
  " data with Sofa.upgrade_convention() before "
284
- "writing to disk if possible."))
282
+ "writing to disk if possible."), stacklevel=2)
285
283
 
286
284
  # setting the netCDF compression parameter
287
285
  use_zlib = compression != 0
@@ -309,12 +307,10 @@ def _write_sofa(filename: str, sofa: sf.Sofa, compression=4, verify=True):
309
307
  for key in all_keys:
310
308
 
311
309
  # skip attributes
312
- # Note: This definition of attribute is blurry:
313
- # lax definition:
314
- # sofa._convention[key]["type"] == "attribute":
315
- # strict definition:
316
- # ("_" in key and not key.startswith("Data_")) or \
317
- # key.count("_") > 1
310
+ # Note: The used definition of attributes is lax. The strict
311
+ # definition would parse `key` and assume an attribute if
312
+ # 1. "_" is in key and key does not start with "DATA_", or
313
+ # 2. key contains more than one "_"
318
314
  #
319
315
  # The strict definition is implicitly included in the SOFA standard
320
316
  # since underscores only occur for variables starting with Data_
@@ -327,7 +323,7 @@ def _write_sofa(filename: str, sofa: sf.Sofa, compression=4, verify=True):
327
323
  sofa._dimensions[key], sofa._api["S"])
328
324
 
329
325
  # create variable and write data
330
- shape = tuple(list(sofa._dimensions[key]))
326
+ shape = list(sofa._dimensions[key])
331
327
  tmp_var = file.createVariable(
332
328
  key.replace("Data_", "Data."), dtype, shape,
333
329
  zlib=use_zlib, complevel=compression)
@@ -391,7 +387,7 @@ def _format_value_for_netcdf(value, key, dtype, dimensions, S):
391
387
 
392
388
  def _format_value_from_netcdf(value, key):
393
389
  """
394
- Format value from NETCDF4 file for saving in a SOFA object
390
+ Format value from NETCDF4 file for saving in a SOFA object.
395
391
 
396
392
  Parameters
397
393
  ----------
@@ -408,7 +404,7 @@ def _format_value_from_netcdf(value, key):
408
404
 
409
405
  if "float" in str(value.dtype) or "int" in str(value.dtype):
410
406
  if np.ma.is_masked(value):
411
- warnings.warn(f"Entry {key} contains missing data")
407
+ warnings.warn(f"Entry {key} contains missing data", stacklevel=3)
412
408
  else:
413
409
  # Convert to numpy array or scalar
414
410
  value = np.asarray(value)