PyOptik 2.0.7__tar.gz → 3.0.0__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.
- {pyoptik-2.0.7 → pyoptik-3.0.0}/.github/workflows/deploy_anaconda.yml +2 -2
- pyoptik-3.0.0/.github/workflows/tests.yml +29 -0
- {pyoptik-2.0.7 → pyoptik-3.0.0}/.gitignore +1 -0
- pyoptik-3.0.0/Makefile +60 -0
- pyoptik-3.0.0/PKG-INFO +420 -0
- {pyoptik-2.0.7 → pyoptik-3.0.0}/PyOptik/__init__.py +5 -2
- pyoptik-3.0.0/PyOptik/__main__.py +124 -0
- {pyoptik-2.0.7 → pyoptik-3.0.0}/PyOptik/_version.py +3 -3
- pyoptik-3.0.0/PyOptik/catalog.py +592 -0
- pyoptik-3.0.0/PyOptik/directories.py +81 -0
- {pyoptik-2.0.7 → pyoptik-3.0.0}/PyOptik/material/base_class.py +76 -9
- {pyoptik-2.0.7 → pyoptik-3.0.0}/PyOptik/material/sellmeier_class.py +49 -16
- {pyoptik-2.0.7 → pyoptik-3.0.0}/PyOptik/material/tabulated_class.py +46 -13
- {pyoptik-2.0.7 → pyoptik-3.0.0}/PyOptik/utils.py +28 -19
- pyoptik-3.0.0/PyOptik.egg-info/PKG-INFO +420 -0
- pyoptik-3.0.0/PyOptik.egg-info/SOURCES.txt +67 -0
- pyoptik-3.0.0/PyOptik.egg-info/entry_points.txt +2 -0
- pyoptik-3.0.0/PyOptik.egg-info/scm_file_list.json +63 -0
- pyoptik-3.0.0/PyOptik.egg-info/scm_version.json +8 -0
- pyoptik-3.0.0/README.rst +360 -0
- {pyoptik-2.0.7 → pyoptik-3.0.0}/docs/examples/group_properties/plot_group_properties.py +7 -6
- {pyoptik-2.0.7 → pyoptik-3.0.0}/docs/examples/sellmeier/plot_bk7.py +3 -2
- {pyoptik-2.0.7 → pyoptik-3.0.0}/docs/examples/sellmeier/plot_compare_glasses.py +7 -6
- {pyoptik-2.0.7 → pyoptik-3.0.0}/docs/examples/sellmeier/plot_silica.py +3 -2
- {pyoptik-2.0.7 → pyoptik-3.0.0}/docs/examples/sellmeier/plot_water.py +3 -2
- {pyoptik-2.0.7 → pyoptik-3.0.0}/docs/examples/tabulated/plot_polyethylene.py +5 -4
- {pyoptik-2.0.7 → pyoptik-3.0.0}/docs/examples/tabulated/plot_silicon_nk.py +5 -4
- {pyoptik-2.0.7 → pyoptik-3.0.0}/docs/examples/tabulated/plot_silver.py +4 -3
- {pyoptik-2.0.7 → pyoptik-3.0.0}/docs/source/code.rst +28 -15
- {pyoptik-2.0.7 → pyoptik-3.0.0}/docs/source/conf.py +1 -9
- {pyoptik-2.0.7 → pyoptik-3.0.0}/docs/source/examples.rst +0 -1
- {pyoptik-2.0.7 → pyoptik-3.0.0}/docs/source/index.rst +2 -2
- pyoptik-3.0.0/docs/source/references.rst +25 -0
- {pyoptik-2.0.7 → pyoptik-3.0.0}/meta.yaml +9 -4
- {pyoptik-2.0.7 → pyoptik-3.0.0}/pyproject.toml +3 -1
- {pyoptik-2.0.7 → pyoptik-3.0.0}/pytest.ini +4 -0
- pyoptik-3.0.0/tests/conftest.py +23 -0
- pyoptik-3.0.0/tests/test_catalog.py +140 -0
- pyoptik-3.0.0/tests/test_docstrings.py +16 -0
- pyoptik-3.0.0/tests/test_main_cli.py +88 -0
- pyoptik-3.0.0/tests/test_material_models.py +64 -0
- pyoptik-3.0.0/tests/test_validation_and_logging.py +16 -0
- pyoptik-2.0.7/PKG-INFO +0 -427
- pyoptik-2.0.7/PyOptik/__main__.py +0 -37
- pyoptik-2.0.7/PyOptik/data/sellmeier/BAF10.yml +0 -59
- pyoptik-2.0.7/PyOptik/data/sellmeier/BAK1.yml +0 -63
- pyoptik-2.0.7/PyOptik/data/sellmeier/BK7.yml +0 -57
- pyoptik-2.0.7/PyOptik/data/sellmeier/SF5.yml +0 -57
- pyoptik-2.0.7/PyOptik/data/sellmeier/ZBLAN.yml +0 -14
- pyoptik-2.0.7/PyOptik/data/sellmeier/acetone.yml +0 -16
- pyoptik-2.0.7/PyOptik/data/sellmeier/air.yml +0 -18
- pyoptik-2.0.7/PyOptik/data/sellmeier/argon.yml +0 -21
- pyoptik-2.0.7/PyOptik/data/sellmeier/crown.yml +0 -61
- pyoptik-2.0.7/PyOptik/data/sellmeier/flint.yml +0 -60
- pyoptik-2.0.7/PyOptik/data/sellmeier/fused_silica.yml +0 -20
- pyoptik-2.0.7/PyOptik/data/sellmeier/germanium.yml +0 -18
- pyoptik-2.0.7/PyOptik/data/sellmeier/lithium_niobate.yml +0 -17
- pyoptik-2.0.7/PyOptik/data/sellmeier/polystyren.yml +0 -17
- pyoptik-2.0.7/PyOptik/data/sellmeier/soda_lime_glass.yml +0 -122
- pyoptik-2.0.7/PyOptik/data/sellmeier/water.yml +0 -16
- pyoptik-2.0.7/PyOptik/data/tabulated/aluminium.yml +0 -219
- pyoptik-2.0.7/PyOptik/data/tabulated/calcium.yml +0 -74
- pyoptik-2.0.7/PyOptik/data/tabulated/copper.yml +0 -62
- pyoptik-2.0.7/PyOptik/data/tabulated/gold.yml +0 -62
- pyoptik-2.0.7/PyOptik/data/tabulated/iron.yml +0 -74
- pyoptik-2.0.7/PyOptik/data/tabulated/nickel.yml +0 -62
- pyoptik-2.0.7/PyOptik/data/tabulated/polyetylene.yml +0 -34
- pyoptik-2.0.7/PyOptik/data/tabulated/silicon.yml +0 -59
- pyoptik-2.0.7/PyOptik/data/tabulated/silver.yml +0 -62
- pyoptik-2.0.7/PyOptik/data/tabulated/sodium.yml +0 -34
- pyoptik-2.0.7/PyOptik/data/tabulated/zinc.yml +0 -163
- pyoptik-2.0.7/PyOptik/directories.py +0 -53
- pyoptik-2.0.7/PyOptik/libraries/__init__.py +0 -0
- pyoptik-2.0.7/PyOptik/libraries/classics.yml +0 -30
- pyoptik-2.0.7/PyOptik/libraries/dielectrics.yml +0 -22
- pyoptik-2.0.7/PyOptik/libraries/metals.yml +0 -20
- pyoptik-2.0.7/PyOptik/libraries/minimal.yml +0 -9
- pyoptik-2.0.7/PyOptik/libraries/organics.yml +0 -11
- pyoptik-2.0.7/PyOptik/libraries/others.yml +0 -4
- pyoptik-2.0.7/PyOptik/libraries/polymers.yml +0 -9
- pyoptik-2.0.7/PyOptik/libraries/repertoire.yml +0 -59
- pyoptik-2.0.7/PyOptik/material_bank.py +0 -529
- pyoptik-2.0.7/PyOptik.egg-info/PKG-INFO +0 -427
- pyoptik-2.0.7/PyOptik.egg-info/SOURCES.txt +0 -108
- pyoptik-2.0.7/README.rst +0 -367
- pyoptik-2.0.7/development/dev_0.py +0 -9
- pyoptik-2.0.7/docs/examples/utils/README.rst +0 -6
- pyoptik-2.0.7/docs/examples/utils/__build_library.py +0 -30
- pyoptik-2.0.7/docs/examples/utils/__download_yml_file.py +0 -28
- pyoptik-2.0.7/docs/examples/utils/create_sellmeier_file.py +0 -29
- pyoptik-2.0.7/docs/examples/utils/create_tabulated_file.py +0 -37
- pyoptik-2.0.7/docs/examples/utils/search_materials.py +0 -23
- pyoptik-2.0.7/docs/source/references.rst +0 -4
- pyoptik-2.0.7/docs/source/sg_execution_times.rst +0 -73
- pyoptik-2.0.7/tests/__init__.py +0 -0
- pyoptik-2.0.7/tests/test_group_properties.py +0 -42
- pyoptik-2.0.7/tests/test_main_cli.py +0 -24
- pyoptik-2.0.7/tests/test_material_bank_extra.py +0 -47
- pyoptik-2.0.7/tests/test_sellmeier.py +0 -183
- pyoptik-2.0.7/tests/test_tabulated.py +0 -128
- pyoptik-2.0.7/tests/test_usual_materials.py +0 -51
- pyoptik-2.0.7/tests/test_utils.py +0 -165
- {pyoptik-2.0.7 → pyoptik-3.0.0}/.coveragerc +0 -0
- {pyoptik-2.0.7 → pyoptik-3.0.0}/.flake8 +0 -0
- {pyoptik-2.0.7 → pyoptik-3.0.0}/.github/dependabot.yml +0 -0
- {pyoptik-2.0.7 → pyoptik-3.0.0}/.github/workflows/deploy_PyPi.yml +0 -0
- {pyoptik-2.0.7 → pyoptik-3.0.0}/.github/workflows/deploy_coverage.yml +0 -0
- {pyoptik-2.0.7 → pyoptik-3.0.0}/.github/workflows/deploy_documentation.yml +0 -0
- {pyoptik-2.0.7 → pyoptik-3.0.0}/.pre-commit-config.yaml +0 -0
- {pyoptik-2.0.7 → pyoptik-3.0.0}/LICENSE +0 -0
- {pyoptik-2.0.7 → pyoptik-3.0.0}/PyOptik/material/__init__.py +0 -0
- {pyoptik-2.0.7 → pyoptik-3.0.0}/PyOptik/material_type.py +0 -0
- {pyoptik-2.0.7 → pyoptik-3.0.0}/PyOptik.egg-info/dependency_links.txt +0 -0
- {pyoptik-2.0.7 → pyoptik-3.0.0}/PyOptik.egg-info/requires.txt +0 -0
- {pyoptik-2.0.7 → pyoptik-3.0.0}/PyOptik.egg-info/top_level.txt +0 -0
- {pyoptik-2.0.7 → pyoptik-3.0.0}/docs/Makefile +0 -0
- {pyoptik-2.0.7 → pyoptik-3.0.0}/docs/examples/README.rst +0 -0
- {pyoptik-2.0.7 → pyoptik-3.0.0}/docs/examples/group_properties/README.rst +0 -0
- {pyoptik-2.0.7 → pyoptik-3.0.0}/docs/examples/sellmeier/README.rst +0 -0
- {pyoptik-2.0.7 → pyoptik-3.0.0}/docs/examples/tabulated/README.rst +0 -0
- {pyoptik-2.0.7 → pyoptik-3.0.0}/docs/images/example_bk7.png +0 -0
- {pyoptik-2.0.7 → pyoptik-3.0.0}/docs/images/logo.png +0 -0
- {pyoptik-2.0.7 → pyoptik-3.0.0}/docs/make.bat +0 -0
- {pyoptik-2.0.7 → pyoptik-3.0.0}/docs/source/_static/default.css +0 -0
- {pyoptik-2.0.7 → pyoptik-3.0.0}/docs/source/_static/thumbnail.png +0 -0
- {pyoptik-2.0.7 → pyoptik-3.0.0}/setup.cfg +0 -0
- {pyoptik-2.0.7/PyOptik/data → pyoptik-3.0.0/tests}/__init__.py +0 -0
- {pyoptik-2.0.7 → pyoptik-3.0.0}/tests/test_base_material_decorator.py +0 -0
- {pyoptik-2.0.7 → pyoptik-3.0.0}/tests/test_utils_extra.py +0 -0
|
@@ -14,8 +14,8 @@ jobs:
|
|
|
14
14
|
linux:
|
|
15
15
|
uses: MartinPdeS/MPSActions/.github/workflows/publish_compiled_package_to_anaconda.yml@master
|
|
16
16
|
with:
|
|
17
|
-
python_versions: '["3.
|
|
17
|
+
python_versions: '["3.13"]'
|
|
18
18
|
apt_package: ""
|
|
19
|
-
os_list: '["ubuntu-latest"
|
|
19
|
+
os_list: '["ubuntu-latest"]'
|
|
20
20
|
secrets:
|
|
21
21
|
ANACONDA_API_TOKEN: ${{ secrets.ANACONDA_API_TOKEN }}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
name: Tests
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: ["master"]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: ["master"]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
test:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
strategy:
|
|
13
|
+
fail-fast: false
|
|
14
|
+
matrix:
|
|
15
|
+
python-version: ["3.10", "3.11", "3.12", "3.13"]
|
|
16
|
+
|
|
17
|
+
steps:
|
|
18
|
+
- uses: actions/checkout@v4
|
|
19
|
+
- uses: actions/setup-python@v5
|
|
20
|
+
with:
|
|
21
|
+
python-version: ${{ matrix.python-version }}
|
|
22
|
+
cache: pip
|
|
23
|
+
- name: Install package and test dependencies
|
|
24
|
+
run: python -m pip install --upgrade pip && python -m pip install -e '.[testing]'
|
|
25
|
+
- name: Run offline test suite
|
|
26
|
+
env:
|
|
27
|
+
MPLBACKEND: Agg
|
|
28
|
+
MPLCONFIGDIR: ${{ runner.temp }}/matplotlib
|
|
29
|
+
run: python -m pytest -m 'not network' --cov=PyOptik --cov-report=term-missing
|
pyoptik-3.0.0/Makefile
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
PYTHON ?= python3.11
|
|
2
|
+
BUILD_DIR ?= build
|
|
3
|
+
DIST_DIR ?= dist
|
|
4
|
+
DOCS_DIR ?= docs
|
|
5
|
+
DOCS_BUILD_DIR ?= $(DOCS_DIR)/build
|
|
6
|
+
|
|
7
|
+
.PHONY: help quality test docs build install uninstall quick rebuild editable \
|
|
8
|
+
setup download-all clean
|
|
9
|
+
|
|
10
|
+
help:
|
|
11
|
+
@echo "PyOptik development targets:"
|
|
12
|
+
@echo " make quality Run static checks"
|
|
13
|
+
@echo " make test Run the offline test suite"
|
|
14
|
+
@echo " make docs Build the documentation with warnings as errors"
|
|
15
|
+
@echo " make build Build source and wheel distributions"
|
|
16
|
+
@echo " make install Install the package"
|
|
17
|
+
@echo " make editable Install the package in editable mode"
|
|
18
|
+
@echo " make setup Download the complete material snapshot"
|
|
19
|
+
@echo " make download-all Download the complete upstream catalog"
|
|
20
|
+
@echo " make quick Run quality checks, tests, and build"
|
|
21
|
+
@echo " make rebuild Clean, then run the quick workflow"
|
|
22
|
+
@echo " make clean Remove generated build and test artifacts"
|
|
23
|
+
|
|
24
|
+
quality:
|
|
25
|
+
$(PYTHON) -m flake8 PyOptik tests
|
|
26
|
+
|
|
27
|
+
test:
|
|
28
|
+
MPLBACKEND=Agg MPLCONFIGDIR=$${TMPDIR:-/tmp}/pyoptik-matplotlib \
|
|
29
|
+
$(PYTHON) -m pytest -m 'not network'
|
|
30
|
+
|
|
31
|
+
docs:
|
|
32
|
+
MPLBACKEND=Agg MPLCONFIGDIR=$${TMPDIR:-/tmp}/pyoptik-matplotlib \
|
|
33
|
+
$(PYTHON) -m sphinx -b html -W --keep-going \
|
|
34
|
+
$(DOCS_DIR)/source $(DOCS_BUILD_DIR)/html
|
|
35
|
+
|
|
36
|
+
build:
|
|
37
|
+
$(PYTHON) -m build --outdir $(DIST_DIR)
|
|
38
|
+
|
|
39
|
+
install:
|
|
40
|
+
$(PYTHON) -m pip install .
|
|
41
|
+
|
|
42
|
+
uninstall:
|
|
43
|
+
$(PYTHON) -m pip uninstall -y PyOptik
|
|
44
|
+
|
|
45
|
+
quick: quality test build
|
|
46
|
+
|
|
47
|
+
rebuild: clean quick
|
|
48
|
+
|
|
49
|
+
editable:
|
|
50
|
+
$(PYTHON) -m pip install --no-build-isolation -e .
|
|
51
|
+
|
|
52
|
+
setup:
|
|
53
|
+
$(PYTHON) -m PyOptik setup $(ARGS)
|
|
54
|
+
|
|
55
|
+
download-all:
|
|
56
|
+
$(PYTHON) -m PyOptik download-all $(ARGS)
|
|
57
|
+
|
|
58
|
+
clean:
|
|
59
|
+
rm -rf $(BUILD_DIR) $(DIST_DIR) $(DOCS_BUILD_DIR) \
|
|
60
|
+
.pytest_cache htmlcov .coverage
|
pyoptik-3.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,420 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: PyOptik
|
|
3
|
+
Version: 3.0.0
|
|
4
|
+
Summary: A package for refractive index values.
|
|
5
|
+
Author-email: Martin Poinsinet de Sivry-Houle <martin.poinsinet.de.sivry@gmail.com>
|
|
6
|
+
License: MIT License
|
|
7
|
+
|
|
8
|
+
Copyright (c) 2020 Martin de Sivry
|
|
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
|
+
Keywords: refractive index,optics
|
|
29
|
+
Classifier: Programming Language :: Python
|
|
30
|
+
Classifier: Programming Language :: Python :: 3
|
|
31
|
+
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
32
|
+
Classifier: Development Status :: 4 - Beta
|
|
33
|
+
Classifier: Topic :: Scientific/Engineering :: Physics
|
|
34
|
+
Classifier: Intended Audience :: Science/Research
|
|
35
|
+
Requires-Python: >=3.10
|
|
36
|
+
Description-Content-Type: text/x-rst
|
|
37
|
+
License-File: LICENSE
|
|
38
|
+
Requires-Dist: pint~=0.24
|
|
39
|
+
Requires-Dist: numpy
|
|
40
|
+
Requires-Dist: matplotlib~=3.8
|
|
41
|
+
Requires-Dist: requests~=2.31
|
|
42
|
+
Requires-Dist: pyyaml~=6.0
|
|
43
|
+
Requires-Dist: MPSPlots
|
|
44
|
+
Requires-Dist: tabulate~=0.9
|
|
45
|
+
Requires-Dist: TypedUnit
|
|
46
|
+
Provides-Extra: testing
|
|
47
|
+
Requires-Dist: pytest<9.0,>=7.4; extra == "testing"
|
|
48
|
+
Requires-Dist: pytest-cov<6,>=2; extra == "testing"
|
|
49
|
+
Requires-Dist: pytest-json-report~=1.5; extra == "testing"
|
|
50
|
+
Requires-Dist: coverage~=7.6; extra == "testing"
|
|
51
|
+
Provides-Extra: documentation
|
|
52
|
+
Requires-Dist: numpydoc==1.6.0; extra == "documentation"
|
|
53
|
+
Requires-Dist: sphinx>=5.1.1; extra == "documentation"
|
|
54
|
+
Requires-Dist: sphinx-gallery==0.15.0; extra == "documentation"
|
|
55
|
+
Requires-Dist: sphinx-rtd-theme==2.0.0; extra == "documentation"
|
|
56
|
+
Requires-Dist: pydata-sphinx-theme==0.14.1; extra == "documentation"
|
|
57
|
+
Provides-Extra: dev
|
|
58
|
+
Requires-Dist: flake8==7.1.1; extra == "dev"
|
|
59
|
+
Dynamic: license-file
|
|
60
|
+
|
|
61
|
+
|logo|
|
|
62
|
+
|
|
63
|
+
.. list-table::
|
|
64
|
+
:widths: 35 65
|
|
65
|
+
:header-rows: 1
|
|
66
|
+
|
|
67
|
+
* - Badge
|
|
68
|
+
- Status
|
|
69
|
+
* - Python versions
|
|
70
|
+
- |python|
|
|
71
|
+
* - Documentation
|
|
72
|
+
- |docs|
|
|
73
|
+
* - Continuous integration
|
|
74
|
+
- |ci/cd|
|
|
75
|
+
* - Test coverage
|
|
76
|
+
- |coverage|
|
|
77
|
+
* - PyPI package
|
|
78
|
+
- |PyPi|
|
|
79
|
+
* - PyPI downloads
|
|
80
|
+
- |PyPi_download|
|
|
81
|
+
* - Anaconda package
|
|
82
|
+
- |anaconda|
|
|
83
|
+
* - Anaconda downloads
|
|
84
|
+
- |anaconda_download|
|
|
85
|
+
|
|
86
|
+
PyOptik
|
|
87
|
+
=======
|
|
88
|
+
|
|
89
|
+
**PyOptik** is a Python library for evaluating optical material properties.
|
|
90
|
+
It provides unit-aware refractive-index calculations, dispersion models,
|
|
91
|
+
tabulated optical constants, group-delay properties, plotting helpers, and a
|
|
92
|
+
catalog interface for the hierarchical `RefractiveIndex.INFO
|
|
93
|
+
<https://refractiveindex.info>`_ database.
|
|
94
|
+
|
|
95
|
+
The library is designed for optical design, photonics simulations,
|
|
96
|
+
electromagnetic modeling, and experimental data analysis.
|
|
97
|
+
|
|
98
|
+
Features
|
|
99
|
+
--------
|
|
100
|
+
|
|
101
|
+
* Sellmeier and other dispersion-formula models.
|
|
102
|
+
* Tabulated complex refractive index data, ``n + i k``.
|
|
103
|
+
* Unit-aware wavelength calculations through ``TypedUnit`` and Pint.
|
|
104
|
+
* Group index, group velocity, group delay, and group-delay dispersion.
|
|
105
|
+
* NumPy-compatible scalar and array evaluation.
|
|
106
|
+
* Plotting helpers for dispersion and absorption data.
|
|
107
|
+
* Hierarchical catalog access using upstream ``shelf / book / page`` identity.
|
|
108
|
+
* Explicit upstream page selection using ``shelf/book/page`` identifiers.
|
|
109
|
+
* Downloadable custom and upstream material data with local caching.
|
|
110
|
+
|
|
111
|
+
Installation
|
|
112
|
+
------------
|
|
113
|
+
|
|
114
|
+
Install the latest release from PyPI:
|
|
115
|
+
|
|
116
|
+
.. code-block:: bash
|
|
117
|
+
|
|
118
|
+
python -m pip install PyOptik
|
|
119
|
+
|
|
120
|
+
The package is also available through Anaconda:
|
|
121
|
+
|
|
122
|
+
.. code-block:: bash
|
|
123
|
+
|
|
124
|
+
conda install -c martinpdes pyoptik
|
|
125
|
+
|
|
126
|
+
Verify the installation with the same interpreter that will run your code:
|
|
127
|
+
|
|
128
|
+
.. code-block:: bash
|
|
129
|
+
|
|
130
|
+
python -c "import PyOptik; print(PyOptik.__version__)"
|
|
131
|
+
|
|
132
|
+
Material data is not bundled with PyOptik. Install the package first, then
|
|
133
|
+
download the upstream snapshot when it is needed:
|
|
134
|
+
|
|
135
|
+
.. code-block:: bash
|
|
136
|
+
|
|
137
|
+
pyoptik setup
|
|
138
|
+
|
|
139
|
+
or from Python:
|
|
140
|
+
|
|
141
|
+
.. code-block:: python
|
|
142
|
+
|
|
143
|
+
from PyOptik import download_snapshot
|
|
144
|
+
|
|
145
|
+
catalog = download_snapshot()
|
|
146
|
+
|
|
147
|
+
First calculation
|
|
148
|
+
-----------------
|
|
149
|
+
|
|
150
|
+
Wavelengths should carry units. This avoids ambiguity between metres,
|
|
151
|
+
micrometres, and nanometres.
|
|
152
|
+
|
|
153
|
+
.. code-block:: python
|
|
154
|
+
|
|
155
|
+
from TypedUnit import ureg
|
|
156
|
+
from PyOptik import MaterialCatalog
|
|
157
|
+
|
|
158
|
+
catalog = MaterialCatalog.from_snapshot()
|
|
159
|
+
bk7 = catalog.get("specs/SCHOTT-optical/P-BK7").load()
|
|
160
|
+
index = bk7.compute_refractive_index(550 * ureg.nanometer)
|
|
161
|
+
|
|
162
|
+
print(index)
|
|
163
|
+
|
|
164
|
+
For backward compatibility, bare numeric wavelengths are interpreted as
|
|
165
|
+
metres. Unit-bearing quantities are recommended for new code.
|
|
166
|
+
|
|
167
|
+
Material models
|
|
168
|
+
---------------
|
|
169
|
+
|
|
170
|
+
Sellmeier materials evaluate a dispersion formula:
|
|
171
|
+
|
|
172
|
+
.. code-block:: python
|
|
173
|
+
|
|
174
|
+
from TypedUnit import ureg
|
|
175
|
+
from PyOptik import MaterialCatalog
|
|
176
|
+
|
|
177
|
+
catalog = MaterialCatalog.from_snapshot()
|
|
178
|
+
silica = catalog.get("main/SiO2/Malitson").load()
|
|
179
|
+
wavelengths = [800, 1310, 1550] * ureg.nanometer
|
|
180
|
+
index = silica.compute_refractive_index(wavelengths)
|
|
181
|
+
|
|
182
|
+
Tabulated materials interpolate complex optical constants:
|
|
183
|
+
|
|
184
|
+
.. code-block:: python
|
|
185
|
+
|
|
186
|
+
from PyOptik import MaterialCatalog
|
|
187
|
+
|
|
188
|
+
catalog = MaterialCatalog.from_snapshot()
|
|
189
|
+
silicon = catalog.get("main/Si/Aspnes").load()
|
|
190
|
+
index = silicon.compute_refractive_index(1.55 * ureg.micrometer)
|
|
191
|
+
|
|
192
|
+
The real part is the refractive index ``n`` and the imaginary part is the
|
|
193
|
+
extinction coefficient ``k``.
|
|
194
|
+
|
|
195
|
+
Validity ranges
|
|
196
|
+
~~~~~~~~~~~~~~~
|
|
197
|
+
|
|
198
|
+
Material data is only valid over the wavelength range supplied by its source.
|
|
199
|
+
Out-of-range behavior can be selected explicitly:
|
|
200
|
+
|
|
201
|
+
.. code-block:: python
|
|
202
|
+
|
|
203
|
+
wavelength = 300 * ureg.nanometer
|
|
204
|
+
|
|
205
|
+
# Default: issue a warning and evaluate.
|
|
206
|
+
index = bk7.compute_refractive_index(wavelength, out_of_range="warn")
|
|
207
|
+
|
|
208
|
+
# Fail fast for production calculations.
|
|
209
|
+
index = bk7.compute_refractive_index(wavelength, out_of_range="raise")
|
|
210
|
+
|
|
211
|
+
# Evaluate at the nearest validity boundary.
|
|
212
|
+
index = bk7.compute_refractive_index(wavelength, out_of_range="clip")
|
|
213
|
+
|
|
214
|
+
Group and pulse properties
|
|
215
|
+
--------------------------
|
|
216
|
+
|
|
217
|
+
Every material model provides group-related quantities:
|
|
218
|
+
|
|
219
|
+
.. code-block:: python
|
|
220
|
+
|
|
221
|
+
wavelength = 1550 * ureg.nanometer
|
|
222
|
+
|
|
223
|
+
group_index = silica.compute_group_index(wavelength)
|
|
224
|
+
group_velocity = silica.compute_group_velocity(wavelength)
|
|
225
|
+
group_delay = silica.compute_group_delay(
|
|
226
|
+
wavelength,
|
|
227
|
+
length=10 * ureg.centimeter,
|
|
228
|
+
)
|
|
229
|
+
group_delay_dispersion = silica.compute_group_delay_dispersion(wavelength)
|
|
230
|
+
|
|
231
|
+
These methods accept scalar or array wavelengths and return unit-aware values.
|
|
232
|
+
|
|
233
|
+
Plotting
|
|
234
|
+
--------
|
|
235
|
+
|
|
236
|
+
Material models include simple dispersion plots:
|
|
237
|
+
|
|
238
|
+
.. code-block:: python
|
|
239
|
+
|
|
240
|
+
from PyOptik import MaterialCatalog
|
|
241
|
+
|
|
242
|
+
catalog = MaterialCatalog.from_snapshot()
|
|
243
|
+
catalog.get("specs/SCHOTT-optical/P-BK7").load().plot()
|
|
244
|
+
catalog.get("main/Au/Johnson").load().plot()
|
|
245
|
+
|
|
246
|
+
For non-interactive environments such as CI or servers, select a headless
|
|
247
|
+
Matplotlib backend before importing plotting code:
|
|
248
|
+
|
|
249
|
+
.. code-block:: python
|
|
250
|
+
|
|
251
|
+
import matplotlib
|
|
252
|
+
matplotlib.use("Agg")
|
|
253
|
+
|
|
254
|
+
Hierarchical material catalog
|
|
255
|
+
-----------------------------
|
|
256
|
+
|
|
257
|
+
RefractiveIndex.INFO organizes data by **shelf**, **book**, and **page**.
|
|
258
|
+
PyOptik preserves this identity so that materials from different sources do
|
|
259
|
+
not collide simply because they share a short name.
|
|
260
|
+
|
|
261
|
+
Load the upstream catalog index:
|
|
262
|
+
|
|
263
|
+
.. code-block:: python
|
|
264
|
+
|
|
265
|
+
from PyOptik import MaterialCatalog
|
|
266
|
+
|
|
267
|
+
catalog = MaterialCatalog.from_upstream()
|
|
268
|
+
|
|
269
|
+
print(catalog.shelves())
|
|
270
|
+
print(catalog.books(shelf="specs"))
|
|
271
|
+
|
|
272
|
+
Download a complete source collection, such as an optical-glass book:
|
|
273
|
+
|
|
274
|
+
.. code-block:: python
|
|
275
|
+
|
|
276
|
+
catalog.download(
|
|
277
|
+
shelf="specs",
|
|
278
|
+
book="SCHOTT-optical",
|
|
279
|
+
)
|
|
280
|
+
|
|
281
|
+
Download the complete optical catalog, including tabulated and formula-based
|
|
282
|
+
materials, with resumable progress tracking:
|
|
283
|
+
|
|
284
|
+
.. code-block:: python
|
|
285
|
+
|
|
286
|
+
catalog.download_all()
|
|
287
|
+
|
|
288
|
+
Each page is stored once and recorded in ``manifest.json`` with its source URL,
|
|
289
|
+
local path, status, timestamp, and SHA-256 checksum. Re-running the command
|
|
290
|
+
uses cached files, so interrupted downloads can resume safely.
|
|
291
|
+
|
|
292
|
+
Access a page by its canonical identifier and load its material model:
|
|
293
|
+
|
|
294
|
+
.. code-block:: python
|
|
295
|
+
|
|
296
|
+
page = catalog.get("specs/SCHOTT-optical/N-BK7")
|
|
297
|
+
bk7 = page.load()
|
|
298
|
+
|
|
299
|
+
Material data is cached in a user data directory. Set
|
|
300
|
+
``PYOPTIK_DATA_DIR`` to choose a different location.
|
|
301
|
+
|
|
302
|
+
The command-line interface provides the canonical catalog workflow:
|
|
303
|
+
|
|
304
|
+
.. code-block:: bash
|
|
305
|
+
|
|
306
|
+
pyoptik setup
|
|
307
|
+
python -m PyOptik download-all --data-root ./refractiveindex-data
|
|
308
|
+
python -m PyOptik download-all --source pages --workers 8
|
|
309
|
+
|
|
310
|
+
After installation, the equivalent console command is ``pyoptik
|
|
311
|
+
download-all --data-root ./refractiveindex-data``.
|
|
312
|
+
|
|
313
|
+
For a beginner-friendly first-time setup, use:
|
|
314
|
+
|
|
315
|
+
.. code-block:: bash
|
|
316
|
+
|
|
317
|
+
pyoptik setup
|
|
318
|
+
|
|
319
|
+
This downloads the complete upstream snapshot, preserves the original
|
|
320
|
+
hierarchy, and can be safely run again. Use ``pyoptik setup --force`` to
|
|
321
|
+
refresh the local snapshot.
|
|
322
|
+
|
|
323
|
+
The same setup is available from Python:
|
|
324
|
+
|
|
325
|
+
.. code-block:: python
|
|
326
|
+
|
|
327
|
+
from PyOptik import download_snapshot
|
|
328
|
+
|
|
329
|
+
catalog = download_snapshot()
|
|
330
|
+
silver = catalog.get("main/Ag/Johnson").load()
|
|
331
|
+
|
|
332
|
+
The default ``download-all`` command downloads one upstream snapshot and
|
|
333
|
+
extracts every material page locally, preserving its ``shelf/book/page``
|
|
334
|
+
hierarchy. This avoids thousands of individual HTTP requests. Existing
|
|
335
|
+
snapshots are reused; pass ``--force`` to refresh the snapshot. The
|
|
336
|
+
``--source pages`` fallback downloads individual pages and supports bounded
|
|
337
|
+
parallelism with ``--workers``. ``--fail-fast`` stops after the first failed
|
|
338
|
+
page, while ``--verbose`` enables detailed diagnostics.
|
|
339
|
+
|
|
340
|
+
Common issues
|
|
341
|
+
-------------
|
|
342
|
+
|
|
343
|
+
* Attach units to wavelengths whenever possible.
|
|
344
|
+
* Use ``out_of_range="raise"`` when extrapolation would invalidate a result.
|
|
345
|
+
* Use the canonical catalog identifier when provenance or source selection
|
|
346
|
+
matters.
|
|
347
|
+
* Use ``MPLBACKEND=Agg`` for documentation builds, CI, and remote servers.
|
|
348
|
+
* If a material cannot be found, run ``pyoptik setup`` or call
|
|
349
|
+
``download_snapshot()`` before loading its canonical page.
|
|
350
|
+
|
|
351
|
+
Development and testing
|
|
352
|
+
-----------------------
|
|
353
|
+
|
|
354
|
+
Clone the repository and install development dependencies:
|
|
355
|
+
|
|
356
|
+
.. code-block:: bash
|
|
357
|
+
|
|
358
|
+
git clone https://github.com/MartinPdeS/PyOptik.git
|
|
359
|
+
cd PyOptik
|
|
360
|
+
python -m pip install -e ".[testing,documentation,dev]"
|
|
361
|
+
|
|
362
|
+
Run the offline test suite:
|
|
363
|
+
|
|
364
|
+
.. code-block:: bash
|
|
365
|
+
|
|
366
|
+
MPLBACKEND=Agg pytest -m "not network"
|
|
367
|
+
|
|
368
|
+
Build the documentation:
|
|
369
|
+
|
|
370
|
+
.. code-block:: bash
|
|
371
|
+
|
|
372
|
+
MPLBACKEND=Agg sphinx-build -b html -W docs/source docs/build/html
|
|
373
|
+
|
|
374
|
+
Network-dependent tests are marked with ``network`` and are excluded from
|
|
375
|
+
normal CI runs.
|
|
376
|
+
|
|
377
|
+
Documentation and references
|
|
378
|
+
----------------------------
|
|
379
|
+
|
|
380
|
+
* `Online documentation <https://martinpdes.github.io/PyOptik/>`_
|
|
381
|
+
* `RefractiveIndex.INFO database <https://github.com/polyanskiy/refractiveindex.info-database>`_
|
|
382
|
+
* `PyOptik source repository <https://github.com/MartinPdeS/PyOptik>`_
|
|
383
|
+
|
|
384
|
+
The material data is sourced from RefractiveIndex.INFO. Refer to each
|
|
385
|
+
material page for its original scientific or manufacturer reference.
|
|
386
|
+
|
|
387
|
+
.. |python| image:: https://img.shields.io/pypi/pyversions/pyoptik.svg
|
|
388
|
+
:alt: Supported Python versions
|
|
389
|
+
:target: https://pypi.org/project/pyoptik/
|
|
390
|
+
|
|
391
|
+
.. |logo| image:: https://github.com/MartinPdeS/PyOptik/raw/master/docs/images/logo.png
|
|
392
|
+
:alt: PyOptik logo
|
|
393
|
+
|
|
394
|
+
.. |docs| image:: https://github.com/martinpdes/pyoptik/actions/workflows/deploy_documentation.yml/badge.svg
|
|
395
|
+
:target: https://martinpdes.github.io/PyOptik/
|
|
396
|
+
:alt: Documentation status
|
|
397
|
+
|
|
398
|
+
.. |ci/cd| image:: https://github.com/martinpdes/pyoptik/actions/workflows/tests.yml/badge.svg
|
|
399
|
+
:target: https://github.com/MartinPdeS/PyOptik/actions/workflows/tests.yml
|
|
400
|
+
:alt: Continuous integration status
|
|
401
|
+
|
|
402
|
+
.. |coverage| image:: https://raw.githubusercontent.com/MartinPdeS/PyOptik/python-coverage-comment-action-data/badge.svg
|
|
403
|
+
:alt: Test coverage
|
|
404
|
+
:target: https://htmlpreview.github.io/?https://github.com/MartinPdeS/PyOptik/blob/python-coverage-comment-action-data/htmlcov/index.html
|
|
405
|
+
|
|
406
|
+
.. |PyPi| image:: https://badge.fury.io/py/pyoptik.svg
|
|
407
|
+
:alt: PyPI version
|
|
408
|
+
:target: https://pypi.org/project/pyoptik/
|
|
409
|
+
|
|
410
|
+
.. |PyPi_download| image:: https://img.shields.io/pypi/dm/pyoptik.svg
|
|
411
|
+
:alt: PyPI downloads
|
|
412
|
+
:target: https://pypistats.org/packages/pyoptik
|
|
413
|
+
|
|
414
|
+
.. |anaconda| image:: https://anaconda.org/martinpdes/pyoptik/badges/version.svg
|
|
415
|
+
:alt: Anaconda version
|
|
416
|
+
:target: https://anaconda.org/martinpdes/pyoptik
|
|
417
|
+
|
|
418
|
+
.. |anaconda_download| image:: https://anaconda.org/martinpdes/pyoptik/badges/downloads.svg
|
|
419
|
+
:alt: Anaconda downloads
|
|
420
|
+
:target: https://anaconda.org/martinpdes/pyoptik
|
|
@@ -4,14 +4,17 @@ try:
|
|
|
4
4
|
except ImportError:
|
|
5
5
|
__version__ = "0.0.0"
|
|
6
6
|
|
|
7
|
+
import logging
|
|
8
|
+
|
|
9
|
+
logging.getLogger(__name__).addHandler(logging.NullHandler())
|
|
10
|
+
|
|
7
11
|
|
|
8
|
-
from .material_bank import MaterialBank
|
|
9
12
|
from .material_type import MaterialType
|
|
13
|
+
from .catalog import MaterialCatalog, MaterialId, MaterialPage, download_snapshot
|
|
10
14
|
|
|
11
15
|
from .material import TabulatedMaterial
|
|
12
16
|
from .material import SellmeierMaterial
|
|
13
17
|
from .material import base_class
|
|
14
18
|
|
|
15
|
-
Material = MaterialBank # For retro-compatibility
|
|
16
19
|
|
|
17
20
|
TIMEOUT = 10 # Default timeout for requests in seconds
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import argparse
|
|
2
|
+
import logging
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
import sys
|
|
5
|
+
|
|
6
|
+
from PyOptik import MaterialCatalog
|
|
7
|
+
|
|
8
|
+
logger = logging.getLogger(__name__)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def main() -> None:
|
|
12
|
+
"""Run the PyOptik material-library command line interface.
|
|
13
|
+
|
|
14
|
+
The default command downloads the complete upstream material snapshot.
|
|
15
|
+
Use ``download-all`` for the explicit catalog download command or its
|
|
16
|
+
page-based fallback mode.
|
|
17
|
+
"""
|
|
18
|
+
parser = argparse.ArgumentParser(
|
|
19
|
+
description="Set up or download the canonical PyOptik material catalog"
|
|
20
|
+
)
|
|
21
|
+
parser.add_argument(
|
|
22
|
+
"command",
|
|
23
|
+
nargs="?",
|
|
24
|
+
default="setup",
|
|
25
|
+
choices=("setup", "download-all"),
|
|
26
|
+
help="Canonical catalog command (default: setup)",
|
|
27
|
+
)
|
|
28
|
+
parser.add_argument(
|
|
29
|
+
"--verbose",
|
|
30
|
+
action="store_true",
|
|
31
|
+
help="Enable detailed download and material-loading logs",
|
|
32
|
+
)
|
|
33
|
+
parser.add_argument(
|
|
34
|
+
"--force",
|
|
35
|
+
action="store_true",
|
|
36
|
+
help="Re-download upstream pages that are already cached",
|
|
37
|
+
)
|
|
38
|
+
parser.add_argument(
|
|
39
|
+
"--fail-fast",
|
|
40
|
+
action="store_true",
|
|
41
|
+
help="Stop the complete upstream download at the first failed page",
|
|
42
|
+
)
|
|
43
|
+
parser.add_argument(
|
|
44
|
+
"--data-root",
|
|
45
|
+
type=Path,
|
|
46
|
+
default=None,
|
|
47
|
+
help="Root directory for the complete upstream catalog",
|
|
48
|
+
)
|
|
49
|
+
parser.add_argument(
|
|
50
|
+
"--source",
|
|
51
|
+
choices=("snapshot", "pages"),
|
|
52
|
+
default="snapshot",
|
|
53
|
+
help="Download source: one upstream snapshot (default) or individual pages",
|
|
54
|
+
)
|
|
55
|
+
parser.add_argument(
|
|
56
|
+
"--workers",
|
|
57
|
+
type=int,
|
|
58
|
+
default=8,
|
|
59
|
+
help="Concurrent page downloads when --source=pages (default: 8)",
|
|
60
|
+
)
|
|
61
|
+
parser.add_argument(
|
|
62
|
+
"--no-progress",
|
|
63
|
+
action="store_true",
|
|
64
|
+
help="Disable the snapshot download progress bar",
|
|
65
|
+
)
|
|
66
|
+
args = parser.parse_args()
|
|
67
|
+
|
|
68
|
+
logging.basicConfig(
|
|
69
|
+
level=logging.DEBUG if args.verbose else logging.INFO,
|
|
70
|
+
format="%(asctime)s %(levelname)s %(name)s: %(message)s",
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
if args.command == "setup" and args.source != "snapshot":
|
|
74
|
+
parser.error("setup always uses the upstream snapshot; use download-all for page mode")
|
|
75
|
+
source = "snapshot" if args.command == "setup" else args.source
|
|
76
|
+
logger.info(
|
|
77
|
+
"Setting up the upstream material catalog"
|
|
78
|
+
if args.command == "setup"
|
|
79
|
+
else "Updating the upstream material catalog"
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
def show_progress(downloaded: int, total: int) -> None:
|
|
83
|
+
"""Render snapshot download progress on the terminal."""
|
|
84
|
+
width = 30
|
|
85
|
+
if total:
|
|
86
|
+
complete = min(width, int(width * downloaded / total))
|
|
87
|
+
bar = "=" * complete + ">" + " " * max(0, width - complete - 1)
|
|
88
|
+
percent = 100 * downloaded / total
|
|
89
|
+
message = (
|
|
90
|
+
f"\rDownloading snapshot [{bar}] {percent:5.1f}% "
|
|
91
|
+
f"({downloaded / 1024**2:.1f}/{total / 1024**2:.1f} MiB)"
|
|
92
|
+
)
|
|
93
|
+
else:
|
|
94
|
+
message = f"\rDownloading snapshot: {downloaded / 1024**2:.1f} MiB"
|
|
95
|
+
print(message, end="", file=sys.stderr, flush=True)
|
|
96
|
+
|
|
97
|
+
progress = None if args.no_progress else show_progress
|
|
98
|
+
if source == "snapshot":
|
|
99
|
+
catalog = MaterialCatalog.from_snapshot(
|
|
100
|
+
data_root=args.data_root,
|
|
101
|
+
force=args.force,
|
|
102
|
+
progress=progress,
|
|
103
|
+
)
|
|
104
|
+
else:
|
|
105
|
+
catalog = MaterialCatalog.from_upstream(data_root=args.data_root)
|
|
106
|
+
if progress:
|
|
107
|
+
print(file=sys.stderr)
|
|
108
|
+
logger.info(
|
|
109
|
+
"Finalizing the complete upstream material catalog"
|
|
110
|
+
if source == "snapshot"
|
|
111
|
+
else "Downloading the complete upstream material catalog"
|
|
112
|
+
)
|
|
113
|
+
if source == "snapshot":
|
|
114
|
+
logger.info("Snapshot download complete; material pages are already available locally")
|
|
115
|
+
return
|
|
116
|
+
catalog.download_all(
|
|
117
|
+
force=args.force,
|
|
118
|
+
continue_on_error=not args.fail_fast,
|
|
119
|
+
workers=args.workers,
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
if __name__ == "__main__":
|
|
124
|
+
main()
|
|
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
|
|
|
18
18
|
commit_id: str | None
|
|
19
19
|
__commit_id__: str | None
|
|
20
20
|
|
|
21
|
-
__version__ = version = '
|
|
22
|
-
__version_tuple__ = version_tuple = (
|
|
21
|
+
__version__ = version = '3.0.0'
|
|
22
|
+
__version_tuple__ = version_tuple = (3, 0, 0)
|
|
23
23
|
|
|
24
|
-
__commit_id__ = commit_id = '
|
|
24
|
+
__commit_id__ = commit_id = 'g8275e8e4b'
|