PyOptik 3.1.0__tar.gz → 3.2.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.
Files changed (100) hide show
  1. {pyoptik-3.1.0 → pyoptik-3.2.0}/CHANGELOG.md +19 -1
  2. {pyoptik-3.1.0 → pyoptik-3.2.0}/PKG-INFO +33 -1
  3. {pyoptik-3.1.0 → pyoptik-3.2.0}/PyOptik/__init__.py +9 -7
  4. {pyoptik-3.1.0 → pyoptik-3.2.0}/PyOptik/_version.py +3 -3
  5. {pyoptik-3.1.0 → pyoptik-3.2.0}/PyOptik/directories.py +1 -0
  6. {pyoptik-3.1.0 → pyoptik-3.2.0}/PyOptik/material/base_class.py +1 -0
  7. {pyoptik-3.1.0 → pyoptik-3.2.0}/PyOptik/utils.py +1 -1
  8. {pyoptik-3.1.0 → pyoptik-3.2.0}/PyOptik.egg-info/PKG-INFO +33 -1
  9. {pyoptik-3.1.0 → pyoptik-3.2.0}/PyOptik.egg-info/SOURCES.txt +11 -0
  10. {pyoptik-3.1.0 → pyoptik-3.2.0}/PyOptik.egg-info/scm_file_list.json +11 -0
  11. {pyoptik-3.1.0 → pyoptik-3.2.0}/PyOptik.egg-info/scm_version.json +2 -2
  12. {pyoptik-3.1.0 → pyoptik-3.2.0}/README.rst +32 -0
  13. pyoptik-3.2.0/docs/examples/catalog/README.rst +6 -0
  14. pyoptik-3.2.0/docs/examples/catalog/plot_catalog_search.py +48 -0
  15. pyoptik-3.2.0/docs/examples/custom_materials/README.rst +6 -0
  16. pyoptik-3.2.0/docs/examples/custom_materials/plot_measured_material.py +54 -0
  17. pyoptik-3.2.0/docs/examples/interfaces/README.rst +6 -0
  18. pyoptik-3.2.0/docs/examples/interfaces/plot_fresnel_angles.py +42 -0
  19. {pyoptik-3.1.0 → pyoptik-3.2.0}/docs/examples/sellmeier/plot_water.py +0 -1
  20. {pyoptik-3.1.0 → pyoptik-3.2.0}/docs/examples/tabulated/plot_silver.py +0 -1
  21. pyoptik-3.2.0/docs/examples/thin_films/README.rst +6 -0
  22. pyoptik-3.2.0/docs/examples/thin_films/plot_antireflection_coating.py +46 -0
  23. pyoptik-3.2.0/docs/examples/thin_films/plot_bragg_mirror.py +50 -0
  24. {pyoptik-3.1.0 → pyoptik-3.2.0}/docs/source/catalog_browser.rst +2 -3
  25. {pyoptik-3.1.0 → pyoptik-3.2.0}/docs/source/code.rst +21 -28
  26. {pyoptik-3.1.0 → pyoptik-3.2.0}/docs/source/conf.py +7 -1
  27. {pyoptik-3.1.0 → pyoptik-3.2.0}/docs/source/conventions.rst +2 -2
  28. {pyoptik-3.1.0 → pyoptik-3.2.0}/docs/source/custom_materials.rst +2 -3
  29. pyoptik-3.2.0/docs/source/examples.rst +19 -0
  30. pyoptik-3.2.0/docs/source/getting_started.rst +66 -0
  31. pyoptik-3.2.0/docs/source/index.rst +70 -0
  32. pyoptik-3.2.0/docs/source/materials_and_catalog.rst +64 -0
  33. {pyoptik-3.1.0 → pyoptik-3.2.0}/docs/source/sg_execution_times.rst +27 -12
  34. {pyoptik-3.1.0 → pyoptik-3.2.0}/tests/conftest.py +2 -2
  35. {pyoptik-3.1.0 → pyoptik-3.2.0}/tests/test_base_material_decorator.py +1 -0
  36. {pyoptik-3.1.0 → pyoptik-3.2.0}/tests/test_utils_extra.py +2 -1
  37. pyoptik-3.1.0/docs/source/examples.rst +0 -14
  38. pyoptik-3.1.0/docs/source/index.rst +0 -16
  39. {pyoptik-3.1.0 → pyoptik-3.2.0}/.coveragerc +0 -0
  40. {pyoptik-3.1.0 → pyoptik-3.2.0}/.flake8 +0 -0
  41. {pyoptik-3.1.0 → pyoptik-3.2.0}/.github/dependabot.yml +0 -0
  42. {pyoptik-3.1.0 → pyoptik-3.2.0}/.github/workflows/deploy_PyPi.yml +0 -0
  43. {pyoptik-3.1.0 → pyoptik-3.2.0}/.github/workflows/deploy_anaconda.yml +0 -0
  44. {pyoptik-3.1.0 → pyoptik-3.2.0}/.github/workflows/deploy_coverage.yml +0 -0
  45. {pyoptik-3.1.0 → pyoptik-3.2.0}/.github/workflows/deploy_documentation.yml +0 -0
  46. {pyoptik-3.1.0 → pyoptik-3.2.0}/.github/workflows/quality.yml +0 -0
  47. {pyoptik-3.1.0 → pyoptik-3.2.0}/.github/workflows/tests.yml +0 -0
  48. {pyoptik-3.1.0 → pyoptik-3.2.0}/.gitignore +0 -0
  49. {pyoptik-3.1.0 → pyoptik-3.2.0}/.pre-commit-config.yaml +0 -0
  50. {pyoptik-3.1.0 → pyoptik-3.2.0}/CONTRIBUTING.md +0 -0
  51. {pyoptik-3.1.0 → pyoptik-3.2.0}/LICENSE +0 -0
  52. {pyoptik-3.1.0 → pyoptik-3.2.0}/Makefile +0 -0
  53. {pyoptik-3.1.0 → pyoptik-3.2.0}/PyOptik/__main__.py +0 -0
  54. {pyoptik-3.1.0 → pyoptik-3.2.0}/PyOptik/catalog.py +0 -0
  55. {pyoptik-3.1.0 → pyoptik-3.2.0}/PyOptik/material/__init__.py +0 -0
  56. {pyoptik-3.1.0 → pyoptik-3.2.0}/PyOptik/material/dataset.py +0 -0
  57. {pyoptik-3.1.0 → pyoptik-3.2.0}/PyOptik/material/sellmeier_class.py +0 -0
  58. {pyoptik-3.1.0 → pyoptik-3.2.0}/PyOptik/material/tabulated_class.py +0 -0
  59. {pyoptik-3.1.0 → pyoptik-3.2.0}/PyOptik/material_type.py +0 -0
  60. {pyoptik-3.1.0 → pyoptik-3.2.0}/PyOptik/thin_film.py +0 -0
  61. {pyoptik-3.1.0 → pyoptik-3.2.0}/PyOptik/tui.py +0 -0
  62. {pyoptik-3.1.0 → pyoptik-3.2.0}/PyOptik.egg-info/dependency_links.txt +0 -0
  63. {pyoptik-3.1.0 → pyoptik-3.2.0}/PyOptik.egg-info/entry_points.txt +0 -0
  64. {pyoptik-3.1.0 → pyoptik-3.2.0}/PyOptik.egg-info/requires.txt +0 -0
  65. {pyoptik-3.1.0 → pyoptik-3.2.0}/PyOptik.egg-info/top_level.txt +0 -0
  66. {pyoptik-3.1.0 → pyoptik-3.2.0}/conda.recipe/meta.yaml +0 -0
  67. {pyoptik-3.1.0 → pyoptik-3.2.0}/docs/Makefile +0 -0
  68. {pyoptik-3.1.0 → pyoptik-3.2.0}/docs/examples/README.rst +0 -0
  69. {pyoptik-3.1.0 → pyoptik-3.2.0}/docs/examples/group_properties/README.rst +0 -0
  70. {pyoptik-3.1.0 → pyoptik-3.2.0}/docs/examples/group_properties/plot_group_properties.py +0 -0
  71. {pyoptik-3.1.0 → pyoptik-3.2.0}/docs/examples/sellmeier/README.rst +0 -0
  72. {pyoptik-3.1.0 → pyoptik-3.2.0}/docs/examples/sellmeier/plot_bk7.py +0 -0
  73. {pyoptik-3.1.0 → pyoptik-3.2.0}/docs/examples/sellmeier/plot_compare_glasses.py +0 -0
  74. {pyoptik-3.1.0 → pyoptik-3.2.0}/docs/examples/sellmeier/plot_silica.py +0 -0
  75. {pyoptik-3.1.0 → pyoptik-3.2.0}/docs/examples/tabulated/README.rst +0 -0
  76. {pyoptik-3.1.0 → pyoptik-3.2.0}/docs/examples/tabulated/plot_polyethylene.py +0 -0
  77. {pyoptik-3.1.0 → pyoptik-3.2.0}/docs/examples/tabulated/plot_silicon_nk.py +0 -0
  78. {pyoptik-3.1.0 → pyoptik-3.2.0}/docs/images/example_bk7.png +0 -0
  79. {pyoptik-3.1.0 → pyoptik-3.2.0}/docs/images/logo.svg +0 -0
  80. {pyoptik-3.1.0 → pyoptik-3.2.0}/docs/make.bat +0 -0
  81. {pyoptik-3.1.0 → pyoptik-3.2.0}/docs/source/_static/default.css +0 -0
  82. {pyoptik-3.1.0 → pyoptik-3.2.0}/docs/source/_static/favicon.png +0 -0
  83. {pyoptik-3.1.0 → pyoptik-3.2.0}/docs/source/_static/logo.svg +0 -0
  84. {pyoptik-3.1.0 → pyoptik-3.2.0}/docs/source/_static/thumbnail.png +0 -0
  85. {pyoptik-3.1.0 → pyoptik-3.2.0}/docs/source/references.rst +0 -0
  86. {pyoptik-3.1.0 → pyoptik-3.2.0}/docs/source/thin_films.rst +0 -0
  87. {pyoptik-3.1.0 → pyoptik-3.2.0}/pyproject.toml +0 -0
  88. {pyoptik-3.1.0 → pyoptik-3.2.0}/pytest.ini +0 -0
  89. {pyoptik-3.1.0 → pyoptik-3.2.0}/setup.cfg +0 -0
  90. {pyoptik-3.1.0 → pyoptik-3.2.0}/tests/__init__.py +0 -0
  91. {pyoptik-3.1.0 → pyoptik-3.2.0}/tests/test_catalog.py +0 -0
  92. {pyoptik-3.1.0 → pyoptik-3.2.0}/tests/test_datasets_and_custom_materials.py +0 -0
  93. {pyoptik-3.1.0 → pyoptik-3.2.0}/tests/test_docstrings.py +0 -0
  94. {pyoptik-3.1.0 → pyoptik-3.2.0}/tests/test_main_cli.py +0 -0
  95. {pyoptik-3.1.0 → pyoptik-3.2.0}/tests/test_material_models.py +0 -0
  96. {pyoptik-3.1.0 → pyoptik-3.2.0}/tests/test_thin_film.py +0 -0
  97. {pyoptik-3.1.0 → pyoptik-3.2.0}/tests/test_tui.py +0 -0
  98. {pyoptik-3.1.0 → pyoptik-3.2.0}/tests/test_validation_and_logging.py +0 -0
  99. {pyoptik-3.1.0 → pyoptik-3.2.0}/tools/next_release_version.py +0 -0
  100. {pyoptik-3.1.0 → pyoptik-3.2.0}/tools/release_tag.py +0 -0
@@ -7,6 +7,23 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [3.2.0] - 2026-09-16
11
+
12
+ ### Added
13
+
14
+ - Task-oriented getting-started and material-catalog guides.
15
+ - Executable gallery examples for measured-material import and YAML round
16
+ trips, Fresnel polarization and Brewster angle, quarter-wave antireflection
17
+ coatings, dielectric Bragg mirrors, and catalog provenance workflows.
18
+ - Direct README links to the principal guides, examples, and API reference.
19
+
20
+ ### Changed
21
+
22
+ - Documentation navigation now groups content into Start here, User guide,
23
+ Learn by example, and Reference sections.
24
+ - The documentation landing page, page titles, API hierarchy, and gallery
25
+ descriptions now use clearer task-oriented language.
26
+
10
27
  ## [3.1.0] - 2026-09-16
11
28
 
12
29
  ### Added
@@ -62,5 +79,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
62
79
  plotting helpers.
63
80
  - Retired logo assets.
64
81
 
65
- [Unreleased]: https://github.com/MartinPdeS/PyOptik/compare/v3.1.0...HEAD
82
+ [Unreleased]: https://github.com/MartinPdeS/PyOptik/compare/v3.2.0...HEAD
83
+ [3.2.0]: https://github.com/MartinPdeS/PyOptik/compare/v3.1.0...v3.2.0
66
84
  [3.1.0]: https://github.com/MartinPdeS/PyOptik/compare/v3.0.5...v3.1.0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: PyOptik
3
- Version: 3.1.0
3
+ Version: 3.2.0
4
4
  Summary: A package for refractive index values.
5
5
  Author-email: Martin Poinsinet de Sivry-Houle <martin.poinsinet.de.sivry@gmail.com>
6
6
  License: MIT License
@@ -96,6 +96,24 @@ catalog interface for the hierarchical `RefractiveIndex.INFO
96
96
  The library is designed for optical design, photonics simulations,
97
97
  electromagnetic modeling, and experimental data analysis.
98
98
 
99
+ Documentation
100
+ -------------
101
+
102
+ The full documentation is organized by task:
103
+
104
+ * `Getting started <https://martinpdes.github.io/PyOptik/getting_started.html>`_
105
+ for installation and a first unit-aware calculation.
106
+ * `Materials and catalog <https://martinpdes.github.io/PyOptik/materials_and_catalog.html>`_
107
+ for model selection, search, provenance, and cache integrity.
108
+ * `Custom materials <https://martinpdes.github.io/PyOptik/custom_materials.html>`_
109
+ for arrays, CSV import, coefficients, validation, and YAML export.
110
+ * `Interfaces and thin films <https://martinpdes.github.io/PyOptik/thin_films.html>`_
111
+ for Fresnel coefficients and coherent multilayer design.
112
+ * `Example gallery <https://martinpdes.github.io/PyOptik/examples.html>`_
113
+ for complete, executable workflows.
114
+ * `API reference <https://martinpdes.github.io/PyOptik/code.html>`_ for public
115
+ classes and functions.
116
+
99
117
  Features
100
118
  --------
101
119
 
@@ -343,6 +361,20 @@ Matplotlib backend before importing plotting code:
343
361
  import matplotlib
344
362
  matplotlib.use("Agg")
345
363
 
364
+ Worked examples
365
+ ---------------
366
+
367
+ The documentation gallery includes downloadable Python scripts and notebooks
368
+ for:
369
+
370
+ * Sellmeier and tabulated material dispersion;
371
+ * group index and group velocity;
372
+ * importing, interpolating, exporting, and reloading measured optical data;
373
+ * s- and p-polarized Fresnel reflectance and Brewster angle;
374
+ * quarter-wave antireflection coatings;
375
+ * multilayer dielectric Bragg mirrors; and
376
+ * catalog search, canonical source selection, and provenance capture.
377
+
346
378
  Hierarchical material catalog
347
379
  -----------------------------
348
380
 
@@ -9,13 +9,15 @@ import logging
9
9
  logging.getLogger(__name__).addHandler(logging.NullHandler())
10
10
 
11
11
 
12
- from .material_type import MaterialType
13
- from .catalog import MaterialCatalog, MaterialId, MaterialPage, download_snapshot
12
+ from .material_type import MaterialType # noqa: E402
13
+ from .catalog import MaterialCatalog, MaterialId, MaterialPage, download_snapshot # noqa: E402
14
14
 
15
- from .material import TabulatedMaterial
16
- from .material import SellmeierMaterial
17
- from .material import FormulaDataset, MaterialDocument, MaterialMetadata, TabulatedDataset, parse_material
18
- from .thin_film import (
15
+ from .material import TabulatedMaterial # noqa: E402
16
+ from .material import SellmeierMaterial # noqa: E402
17
+ from .material import ( # noqa: E402
18
+ FormulaDataset, MaterialDocument, MaterialMetadata, TabulatedDataset, parse_material,
19
+ )
20
+ from .thin_film import ( # noqa: E402
19
21
  FresnelResult,
20
22
  ThinFilmLayer,
21
23
  ThinFilmResult,
@@ -24,7 +26,7 @@ from .thin_film import (
24
26
  fresnel_coefficients,
25
27
  thin_film_stack,
26
28
  )
27
- from .material import base_class
29
+ from .material import base_class # noqa: E402
28
30
 
29
31
 
30
32
  TIMEOUT = 10 # Default timeout for requests in seconds
@@ -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 = '3.1.0'
22
- __version_tuple__ = version_tuple = (3, 1, 0)
21
+ __version__ = version = '3.2.0'
22
+ __version_tuple__ = version_tuple = (3, 2, 0)
23
23
 
24
- __commit_id__ = commit_id = 'g705a5ec86'
24
+ __commit_id__ = commit_id = 'g7c8410160'
@@ -54,6 +54,7 @@ user_data_path = _default_user_data_path()
54
54
  user_sellmeier_data_path = user_data_path / "sellmeier"
55
55
  user_tabulated_data_path = user_data_path / "tabulated"
56
56
 
57
+
57
58
  def material_paths(material_type):
58
59
  """Return the user data directory for a material type.
59
60
 
@@ -10,6 +10,7 @@ from TypedUnit import Length, AnyUnit, Time, ureg, validate_units
10
10
 
11
11
  logger = logging.getLogger(__name__)
12
12
 
13
+
13
14
  class BaseMaterial(object):
14
15
  """Common interface for refractive-index material models.
15
16
 
@@ -103,6 +103,6 @@ def download_yml_file(
103
103
  except requests.exceptions.HTTPError as e:
104
104
  logger.error("HTTP error while downloading %s: %s", url, e)
105
105
  raise
106
- except Exception as e:
106
+ except Exception:
107
107
  logger.exception("Unexpected error while saving %s to %s", url, file_path)
108
108
  raise
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: PyOptik
3
- Version: 3.1.0
3
+ Version: 3.2.0
4
4
  Summary: A package for refractive index values.
5
5
  Author-email: Martin Poinsinet de Sivry-Houle <martin.poinsinet.de.sivry@gmail.com>
6
6
  License: MIT License
@@ -96,6 +96,24 @@ catalog interface for the hierarchical `RefractiveIndex.INFO
96
96
  The library is designed for optical design, photonics simulations,
97
97
  electromagnetic modeling, and experimental data analysis.
98
98
 
99
+ Documentation
100
+ -------------
101
+
102
+ The full documentation is organized by task:
103
+
104
+ * `Getting started <https://martinpdes.github.io/PyOptik/getting_started.html>`_
105
+ for installation and a first unit-aware calculation.
106
+ * `Materials and catalog <https://martinpdes.github.io/PyOptik/materials_and_catalog.html>`_
107
+ for model selection, search, provenance, and cache integrity.
108
+ * `Custom materials <https://martinpdes.github.io/PyOptik/custom_materials.html>`_
109
+ for arrays, CSV import, coefficients, validation, and YAML export.
110
+ * `Interfaces and thin films <https://martinpdes.github.io/PyOptik/thin_films.html>`_
111
+ for Fresnel coefficients and coherent multilayer design.
112
+ * `Example gallery <https://martinpdes.github.io/PyOptik/examples.html>`_
113
+ for complete, executable workflows.
114
+ * `API reference <https://martinpdes.github.io/PyOptik/code.html>`_ for public
115
+ classes and functions.
116
+
99
117
  Features
100
118
  --------
101
119
 
@@ -343,6 +361,20 @@ Matplotlib backend before importing plotting code:
343
361
  import matplotlib
344
362
  matplotlib.use("Agg")
345
363
 
364
+ Worked examples
365
+ ---------------
366
+
367
+ The documentation gallery includes downloadable Python scripts and notebooks
368
+ for:
369
+
370
+ * Sellmeier and tabulated material dispersion;
371
+ * group index and group velocity;
372
+ * importing, interpolating, exporting, and reloading measured optical data;
373
+ * s- and p-polarized Fresnel reflectance and Brewster angle;
374
+ * quarter-wave antireflection coatings;
375
+ * multilayer dielectric Bragg mirrors; and
376
+ * catalog search, canonical source selection, and provenance capture.
377
+
346
378
  Hierarchical material catalog
347
379
  -----------------------------
348
380
 
@@ -42,8 +42,14 @@ conda.recipe/meta.yaml
42
42
  docs/Makefile
43
43
  docs/make.bat
44
44
  docs/examples/README.rst
45
+ docs/examples/catalog/README.rst
46
+ docs/examples/catalog/plot_catalog_search.py
47
+ docs/examples/custom_materials/README.rst
48
+ docs/examples/custom_materials/plot_measured_material.py
45
49
  docs/examples/group_properties/README.rst
46
50
  docs/examples/group_properties/plot_group_properties.py
51
+ docs/examples/interfaces/README.rst
52
+ docs/examples/interfaces/plot_fresnel_angles.py
47
53
  docs/examples/sellmeier/README.rst
48
54
  docs/examples/sellmeier/plot_bk7.py
49
55
  docs/examples/sellmeier/plot_compare_glasses.py
@@ -53,6 +59,9 @@ docs/examples/tabulated/README.rst
53
59
  docs/examples/tabulated/plot_polyethylene.py
54
60
  docs/examples/tabulated/plot_silicon_nk.py
55
61
  docs/examples/tabulated/plot_silver.py
62
+ docs/examples/thin_films/README.rst
63
+ docs/examples/thin_films/plot_antireflection_coating.py
64
+ docs/examples/thin_films/plot_bragg_mirror.py
56
65
  docs/images/example_bk7.png
57
66
  docs/images/logo.svg
58
67
  docs/source/catalog_browser.rst
@@ -61,7 +70,9 @@ docs/source/conf.py
61
70
  docs/source/conventions.rst
62
71
  docs/source/custom_materials.rst
63
72
  docs/source/examples.rst
73
+ docs/source/getting_started.rst
64
74
  docs/source/index.rst
75
+ docs/source/materials_and_catalog.rst
65
76
  docs/source/references.rst
66
77
  docs/source/sg_execution_times.rst
67
78
  docs/source/thin_films.rst
@@ -33,8 +33,14 @@
33
33
  "conda.recipe/meta.yaml",
34
34
  "docs/Makefile",
35
35
  "docs/examples/README.rst",
36
+ "docs/examples/catalog/README.rst",
37
+ "docs/examples/catalog/plot_catalog_search.py",
38
+ "docs/examples/custom_materials/README.rst",
39
+ "docs/examples/custom_materials/plot_measured_material.py",
36
40
  "docs/examples/group_properties/README.rst",
37
41
  "docs/examples/group_properties/plot_group_properties.py",
42
+ "docs/examples/interfaces/README.rst",
43
+ "docs/examples/interfaces/plot_fresnel_angles.py",
38
44
  "docs/examples/sellmeier/README.rst",
39
45
  "docs/examples/sellmeier/plot_bk7.py",
40
46
  "docs/examples/sellmeier/plot_compare_glasses.py",
@@ -44,6 +50,9 @@
44
50
  "docs/examples/tabulated/plot_polyethylene.py",
45
51
  "docs/examples/tabulated/plot_silicon_nk.py",
46
52
  "docs/examples/tabulated/plot_silver.py",
53
+ "docs/examples/thin_films/README.rst",
54
+ "docs/examples/thin_films/plot_antireflection_coating.py",
55
+ "docs/examples/thin_films/plot_bragg_mirror.py",
47
56
  "docs/images/example_bk7.png",
48
57
  "docs/images/logo.svg",
49
58
  "docs/make.bat",
@@ -57,7 +66,9 @@
57
66
  "docs/source/conventions.rst",
58
67
  "docs/source/custom_materials.rst",
59
68
  "docs/source/examples.rst",
69
+ "docs/source/getting_started.rst",
60
70
  "docs/source/index.rst",
71
+ "docs/source/materials_and_catalog.rst",
61
72
  "docs/source/references.rst",
62
73
  "docs/source/sg_execution_times.rst",
63
74
  "docs/source/thin_films.rst",
@@ -1,7 +1,7 @@
1
1
  {
2
- "tag": "3.1.0",
2
+ "tag": "3.2.0",
3
3
  "distance": 0,
4
- "node": "g705a5ec861bd23f0f24cab4800260b0b528ac4cf",
4
+ "node": "g7c8410160ff259451a9478f2f563f8a1188e1ed7",
5
5
  "dirty": true,
6
6
  "branch": "HEAD",
7
7
  "node_date": "2026-09-16"
@@ -35,6 +35,24 @@ catalog interface for the hierarchical `RefractiveIndex.INFO
35
35
  The library is designed for optical design, photonics simulations,
36
36
  electromagnetic modeling, and experimental data analysis.
37
37
 
38
+ Documentation
39
+ -------------
40
+
41
+ The full documentation is organized by task:
42
+
43
+ * `Getting started <https://martinpdes.github.io/PyOptik/getting_started.html>`_
44
+ for installation and a first unit-aware calculation.
45
+ * `Materials and catalog <https://martinpdes.github.io/PyOptik/materials_and_catalog.html>`_
46
+ for model selection, search, provenance, and cache integrity.
47
+ * `Custom materials <https://martinpdes.github.io/PyOptik/custom_materials.html>`_
48
+ for arrays, CSV import, coefficients, validation, and YAML export.
49
+ * `Interfaces and thin films <https://martinpdes.github.io/PyOptik/thin_films.html>`_
50
+ for Fresnel coefficients and coherent multilayer design.
51
+ * `Example gallery <https://martinpdes.github.io/PyOptik/examples.html>`_
52
+ for complete, executable workflows.
53
+ * `API reference <https://martinpdes.github.io/PyOptik/code.html>`_ for public
54
+ classes and functions.
55
+
38
56
  Features
39
57
  --------
40
58
 
@@ -282,6 +300,20 @@ Matplotlib backend before importing plotting code:
282
300
  import matplotlib
283
301
  matplotlib.use("Agg")
284
302
 
303
+ Worked examples
304
+ ---------------
305
+
306
+ The documentation gallery includes downloadable Python scripts and notebooks
307
+ for:
308
+
309
+ * Sellmeier and tabulated material dispersion;
310
+ * group index and group velocity;
311
+ * importing, interpolating, exporting, and reloading measured optical data;
312
+ * s- and p-polarized Fresnel reflectance and Brewster angle;
313
+ * quarter-wave antireflection coatings;
314
+ * multilayer dielectric Bragg mirrors; and
315
+ * catalog search, canonical source selection, and provenance capture.
316
+
285
317
  Hierarchical material catalog
286
318
  -----------------------------
287
319
 
@@ -0,0 +1,6 @@
1
+ Catalog discovery
2
+ =================
3
+
4
+ Search the local RefractiveIndex.INFO snapshot, filter candidates, and retain
5
+ source provenance alongside calculated results.
6
+
@@ -0,0 +1,48 @@
1
+ """
2
+ Search materials and inspect provenance
3
+ =======================================
4
+
5
+ Find locally available BK7 datasets, inspect their canonical identities, and
6
+ compare representative glass pages at a standard wavelength.
7
+ """
8
+
9
+ # %%
10
+ import matplotlib.pyplot as plt
11
+ from TypedUnit import ureg
12
+
13
+ from PyOptik import MaterialCatalog
14
+
15
+
16
+ catalog = MaterialCatalog.from_snapshot()
17
+ matches = catalog.search("BK7", shelf="specs", available=True)
18
+
19
+ print(f"Found {len(matches)} cached BK7 pages")
20
+ for page in matches[:5]:
21
+ print(page.id.key, "—", page.description)
22
+
23
+ # %%
24
+ # Canonical IDs make source selection explicit and reproducible.
25
+ identifiers = [
26
+ "specs/SCHOTT-optical/N-BK7",
27
+ "specs/OHARA-optical/S-BSL7",
28
+ ]
29
+ wavelength = 587.6 * ureg.nanometer
30
+ labels, indices = [], []
31
+
32
+ for identifier in identifiers:
33
+ page = catalog.get(identifier)
34
+ material = page.load()
35
+ labels.append(page.id.page)
36
+ indices.append(float(material.n(wavelength, out_of_range="raise")))
37
+ print(material.provenance)
38
+
39
+ # %%
40
+ figure, axis = plt.subplots(figsize=(6, 3.5), layout="constrained")
41
+ axis.bar(labels, indices, color=["tab:blue", "tab:orange"])
42
+ axis.set(
43
+ ylabel="Refractive index at 587.6 nm",
44
+ title="Catalog-backed glass comparison",
45
+ ylim=(1.50, 1.54),
46
+ )
47
+ axis.grid(axis="y", alpha=0.25)
48
+ plt.show()
@@ -0,0 +1,6 @@
1
+ Custom materials
2
+ ================
3
+
4
+ Build optical materials from measured arrays, validate their interpolation,
5
+ and round-trip them through PyOptik's YAML representation.
6
+
@@ -0,0 +1,54 @@
1
+ """
2
+ Create and export a measured material
3
+ =====================================
4
+
5
+ This example builds a complex refractive-index model from measured arrays,
6
+ evaluates the interpolation, and verifies a YAML export/reload round trip.
7
+ """
8
+
9
+ # %%
10
+ from tempfile import TemporaryDirectory
11
+
12
+ import matplotlib.pyplot as plt
13
+ import numpy
14
+ from TypedUnit import ureg
15
+
16
+ from PyOptik import TabulatedMaterial
17
+
18
+
19
+ wavelength_samples = numpy.array([400, 475, 550, 625, 700]) * ureg.nanometer
20
+ measured_n = [1.58, 1.56, 1.545, 1.535, 1.528]
21
+ measured_k = [0.030, 0.018, 0.010, 0.006, 0.004]
22
+
23
+ material = TabulatedMaterial.from_arrays(
24
+ "measured-film",
25
+ wavelength_samples,
26
+ n=measured_n,
27
+ k=measured_k,
28
+ interpolation="pchip",
29
+ reference="Illustrative ellipsometry dataset",
30
+ conditions={"temperature": "293 K"},
31
+ )
32
+
33
+ # %%
34
+ # Exported files use the same validated schema as catalog materials.
35
+ with TemporaryDirectory() as directory:
36
+ path = material.to_yaml(f"{directory}/measured-film.yml")
37
+ restored = TabulatedMaterial("measured-film", file_path=path, interpolation="pchip")
38
+ assert restored.reference == material.reference
39
+
40
+ # %%
41
+ wavelengths = numpy.linspace(400, 700, 301) * ureg.nanometer
42
+ index = material.compute_refractive_index(wavelengths, out_of_range="raise")
43
+
44
+ figure, (axis_n, axis_k) = plt.subplots(2, 1, sharex=True, layout="constrained")
45
+ axis_n.plot(wavelengths.magnitude, index.real, label="PCHIP interpolation")
46
+ axis_n.scatter(wavelength_samples.magnitude, measured_n, label="Measurements")
47
+ axis_n.set(ylabel="Refractive index n", title="User-defined optical constants")
48
+ axis_n.legend()
49
+
50
+ axis_k.plot(wavelengths.magnitude, index.imag, color="tab:red")
51
+ axis_k.scatter(wavelength_samples.magnitude, measured_k, color="tab:red")
52
+ axis_k.set(xlabel="Wavelength [nm]", ylabel="Extinction coefficient k")
53
+
54
+ plt.show()
@@ -0,0 +1,6 @@
1
+ Fresnel interfaces
2
+ ==================
3
+
4
+ Explore polarization, characteristic angles, and total internal reflection at
5
+ a single planar interface.
6
+
@@ -0,0 +1,42 @@
1
+ """
2
+ Fresnel reflectance versus incidence angle
3
+ ==========================================
4
+
5
+ Compare s and p polarization at an air-to-glass interface and identify the
6
+ Brewster angle where p-polarized reflection vanishes.
7
+ """
8
+
9
+ # %%
10
+ import matplotlib.pyplot as plt
11
+ import numpy
12
+ from TypedUnit import ureg
13
+
14
+ from PyOptik import brewster_angle, fresnel_coefficients
15
+
16
+
17
+ angles = numpy.linspace(0, 89, 500) * ureg.degree
18
+ reflectance_s = numpy.array([
19
+ fresnel_coefficients(1.0, 1.5, angle, polarization="s").reflectance
20
+ for angle in angles
21
+ ])
22
+ reflectance_p = numpy.array([
23
+ fresnel_coefficients(1.0, 1.5, angle, polarization="p").reflectance
24
+ for angle in angles
25
+ ])
26
+ brewster = brewster_angle(1.0, 1.5).to(ureg.degree).magnitude
27
+
28
+ # %%
29
+ figure, axis = plt.subplots(layout="constrained")
30
+ axis.plot(angles.magnitude, reflectance_s, label="s polarization")
31
+ axis.plot(angles.magnitude, reflectance_p, label="p polarization")
32
+ axis.axvline(brewster, color="black", linestyle="--", label=f"Brewster: {brewster:.1f}°")
33
+ axis.set(
34
+ xlabel="Incidence angle [degree]",
35
+ ylabel="Reflectance",
36
+ title="Air–glass Fresnel reflectance",
37
+ xlim=(0, 90),
38
+ ylim=(0, 1),
39
+ )
40
+ axis.grid(alpha=0.25)
41
+ axis.legend()
42
+ plt.show()
@@ -7,7 +7,6 @@ This module demonstrates the usage of the PyOptik library to calculate and plot
7
7
  """
8
8
 
9
9
  # %%
10
- import numpy
11
10
  from TypedUnit import ureg
12
11
 
13
12
  from PyOptik import MaterialCatalog
@@ -7,7 +7,6 @@ This module demonstrates the usage of the PyOptik library to calculate and plot
7
7
  """
8
8
 
9
9
  # %%
10
- import numpy
11
10
  from TypedUnit import ureg
12
11
 
13
12
  from PyOptik import MaterialCatalog
@@ -0,0 +1,6 @@
1
+ Thin-film coatings
2
+ ==================
3
+
4
+ Design coherent antireflection and dielectric-mirror stacks and inspect their
5
+ spectral power response.
6
+
@@ -0,0 +1,46 @@
1
+ """
2
+ Quarter-wave antireflection coating
3
+ ===================================
4
+
5
+ Design the ideal single-layer coating for an air-to-glass interface and compare
6
+ its spectrum with the uncoated substrate.
7
+ """
8
+
9
+ # %%
10
+ import matplotlib.pyplot as plt
11
+ import numpy
12
+ from TypedUnit import ureg
13
+
14
+ from PyOptik import ThinFilmLayer, thin_film_stack
15
+
16
+
17
+ design_wavelength = 550 * ureg.nanometer
18
+ substrate_index = 1.52
19
+ coating_index = numpy.sqrt(substrate_index)
20
+ coating_thickness = design_wavelength / (4 * coating_index)
21
+ wavelengths = numpy.linspace(350, 900, 600) * ureg.nanometer
22
+
23
+ uncoated = thin_film_stack(
24
+ wavelengths,
25
+ [],
26
+ substrate_index=substrate_index,
27
+ )
28
+ coated = thin_film_stack(
29
+ wavelengths,
30
+ [ThinFilmLayer(coating_index, coating_thickness)],
31
+ substrate_index=substrate_index,
32
+ )
33
+
34
+ # %%
35
+ figure, axis = plt.subplots(layout="constrained")
36
+ axis.plot(wavelengths.magnitude, 100 * uncoated.reflectance, label="Uncoated glass")
37
+ axis.plot(wavelengths.magnitude, 100 * coated.reflectance, label="Quarter-wave coating")
38
+ axis.axvline(design_wavelength.magnitude, color="black", linestyle="--", alpha=0.6)
39
+ axis.set(
40
+ xlabel="Wavelength [nm]",
41
+ ylabel="Reflectance [%]",
42
+ title="Single-layer antireflection coating",
43
+ )
44
+ axis.grid(alpha=0.25)
45
+ axis.legend()
46
+ plt.show()
@@ -0,0 +1,50 @@
1
+ """
2
+ Dielectric Bragg mirror
3
+ =======================
4
+
5
+ Build an alternating high/low-index quarter-wave stack and observe how adding
6
+ layer pairs increases reflectance around the design wavelength.
7
+ """
8
+
9
+ # %%
10
+ import matplotlib.pyplot as plt
11
+ import numpy
12
+ from TypedUnit import ureg
13
+
14
+ from PyOptik import ThinFilmLayer, thin_film_stack
15
+
16
+
17
+ design_wavelength = 800 * ureg.nanometer
18
+ high_index, low_index = 2.25, 1.45
19
+ wavelengths = numpy.linspace(500, 1100, 700) * ureg.nanometer
20
+
21
+
22
+ def mirror_layers(pair_count):
23
+ """Return ``pair_count`` high/low quarter-wave layer pairs."""
24
+ pair = [
25
+ ThinFilmLayer(high_index, design_wavelength / (4 * high_index)),
26
+ ThinFilmLayer(low_index, design_wavelength / (4 * low_index)),
27
+ ]
28
+ return pair * pair_count
29
+
30
+
31
+ # %%
32
+ figure, axis = plt.subplots(layout="constrained")
33
+ for pair_count in (2, 4, 8):
34
+ result = thin_film_stack(
35
+ wavelengths,
36
+ mirror_layers(pair_count),
37
+ substrate_index=1.52,
38
+ )
39
+ axis.plot(wavelengths.magnitude, 100 * result.reflectance, label=f"{pair_count} pairs")
40
+
41
+ axis.axvline(design_wavelength.magnitude, color="black", linestyle="--", alpha=0.6)
42
+ axis.set(
43
+ xlabel="Wavelength [nm]",
44
+ ylabel="Reflectance [%]",
45
+ title="Quarter-wave dielectric mirror",
46
+ ylim=(0, 101),
47
+ )
48
+ axis.grid(alpha=0.25)
49
+ axis.legend()
50
+ plt.show()
@@ -1,5 +1,5 @@
1
- Terminal catalog browser
2
- ========================
1
+ Catalog browser
2
+ ===============
3
3
 
4
4
  PyOptik includes an optional full-screen terminal interface for exploring a
5
5
  downloaded RefractiveIndex.INFO snapshot. It uses Textual and is installed
@@ -39,4 +39,3 @@ field and ``q`` to quit.
39
39
  If no snapshot exists, the command reports its expected location and asks you
40
40
  to run ``pyoptik setup``. The browser never silently downloads or modifies
41
41
  catalog data.
42
-