PyOptik 1.11.0__tar.gz → 1.12.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-1.11.0 → pyoptik-1.12.0}/.gitignore +1 -1
- {pyoptik-1.11.0 → pyoptik-1.12.0}/PKG-INFO +6 -1
- {pyoptik-1.11.0 → pyoptik-1.12.0}/PyOptik/__main__.py +1 -1
- {pyoptik-1.11.0 → pyoptik-1.12.0}/PyOptik/_version.py +2 -2
- {pyoptik-1.11.0 → pyoptik-1.12.0}/PyOptik/material/base_class.py +54 -7
- {pyoptik-1.11.0 → pyoptik-1.12.0}/PyOptik/material/sellmeier_class.py +12 -12
- {pyoptik-1.11.0 → pyoptik-1.12.0}/PyOptik/material/tabulated_class.py +9 -9
- {pyoptik-1.11.0 → pyoptik-1.12.0}/PyOptik/units.py +2 -1
- {pyoptik-1.11.0 → pyoptik-1.12.0}/PyOptik.egg-info/PKG-INFO +6 -1
- {pyoptik-1.11.0 → pyoptik-1.12.0}/PyOptik.egg-info/SOURCES.txt +1 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/README.rst +5 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/pyproject.toml +1 -0
- pyoptik-1.12.0/tests/test_group_properties.py +27 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/.flake8 +0 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/.github/dependabot.yml +0 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/.github/workflows/deploy_PyPi.yml +0 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/.github/workflows/deploy_anaconda.yml +0 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/.github/workflows/deploy_coverage.yml +0 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/.github/workflows/deploy_documentation.yml +0 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/LICENSE +0 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/PyOptik/__init__.py +0 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/PyOptik/data/__init__.py +0 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/PyOptik/data/sellmeier/BAK1.yml +0 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/PyOptik/data/sellmeier/BK7.yml +0 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/PyOptik/data/sellmeier/SF5.yml +0 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/PyOptik/data/sellmeier/ZBLAN.yml +0 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/PyOptik/data/sellmeier/acetone.yml +0 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/PyOptik/data/sellmeier/air.yml +0 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/PyOptik/data/sellmeier/argon.yml +0 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/PyOptik/data/sellmeier/crown.yml +0 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/PyOptik/data/sellmeier/flint.yml +0 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/PyOptik/data/sellmeier/fused_silica.yml +0 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/PyOptik/data/sellmeier/germanium.yml +0 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/PyOptik/data/sellmeier/lithium_niobate.yml +0 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/PyOptik/data/sellmeier/polystyren.yml +0 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/PyOptik/data/sellmeier/soda_lime_glass.yml +0 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/PyOptik/data/sellmeier/water.yml +0 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/PyOptik/data/tabulated/aluminium.yml +0 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/PyOptik/data/tabulated/calcium.yml +0 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/PyOptik/data/tabulated/copper.yml +0 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/PyOptik/data/tabulated/gold.yml +0 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/PyOptik/data/tabulated/iron.yml +0 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/PyOptik/data/tabulated/nickel.yml +0 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/PyOptik/data/tabulated/polyetylene.yml +0 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/PyOptik/data/tabulated/silicon.yml +0 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/PyOptik/data/tabulated/silver.yml +0 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/PyOptik/data/tabulated/sodium.yml +0 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/PyOptik/data/tabulated/zinc.yml +0 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/PyOptik/directories.py +0 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/PyOptik/libraries/__init__.py +0 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/PyOptik/libraries/classics.yml +0 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/PyOptik/libraries/dielectrics.yml +0 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/PyOptik/libraries/metals.yml +0 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/PyOptik/libraries/minimal.yml +0 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/PyOptik/libraries/organics.yml +0 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/PyOptik/libraries/others.yml +0 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/PyOptik/libraries/polymers.yml +0 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/PyOptik/libraries/repertoire.yml +0 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/PyOptik/material/__init__.py +0 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/PyOptik/material_bank.py +0 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/PyOptik/material_type.py +0 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/PyOptik/utils.py +0 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/PyOptik.egg-info/dependency_links.txt +0 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/PyOptik.egg-info/requires.txt +0 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/PyOptik.egg-info/top_level.txt +0 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/development/dev_0.py +0 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/docs/Makefile +0 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/docs/examples/README.rst +0 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/docs/examples/sellmeier/README.rst +0 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/docs/examples/sellmeier/plot_bk7.py +0 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/docs/examples/sellmeier/plot_silica.py +0 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/docs/examples/sellmeier/plot_water.py +0 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/docs/examples/tabulated/README.rst +0 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/docs/examples/tabulated/plot_sf5.py +0 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/docs/examples/tabulated/plot_silver.py +0 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/docs/examples/utils/README.rst +0 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/docs/examples/utils/__build_library.py +0 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/docs/examples/utils/__download_yml_file.py +0 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/docs/examples/utils/create_sellmeier_file.py +0 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/docs/examples/utils/create_tabulated_file.py +0 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/docs/images/example_bk7.png +0 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/docs/images/logo.png +0 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/docs/make.bat +0 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/docs/source/_static/default.css +0 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/docs/source/_static/thumbnail.png +0 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/docs/source/code.rst +0 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/docs/source/conf.py +0 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/docs/source/gallery/index.rst +0 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/docs/source/index.rst +0 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/docs/source/references.rst +0 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/meta.yaml +0 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/setup.cfg +0 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/tests/__init__.py +0 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/tests/test_base_material_decorator.py +0 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/tests/test_material_bank_extra.py +0 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/tests/test_sellmeier.py +0 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/tests/test_tabulated.py +0 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/tests/test_usual_materials.py +0 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/tests/test_utils.py +0 -0
- {pyoptik-1.11.0 → pyoptik-1.12.0}/tests/test_utils_extra.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: PyOptik
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.12.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
|
|
@@ -92,6 +92,7 @@ Features
|
|
|
92
92
|
- **Simulation Ready**: Ideal for light-matter interaction simulations, particularly in optics and photonics.
|
|
93
93
|
- **Simple API**: Easy-to-use API that integrates well with other Python libraries.
|
|
94
94
|
- **Open Source**: Fully open-source.
|
|
95
|
+
- **Group Index and Velocity**: Compute group index and group velocity directly from material objects.
|
|
95
96
|
|
|
96
97
|
Installation
|
|
97
98
|
************
|
|
@@ -174,6 +175,10 @@ After installing PyOptik and building the material library, you can easily acces
|
|
|
174
175
|
bk7 = MaterialBank.BK7
|
|
175
176
|
n = bk7.compute_refractive_index(0.55e-6)
|
|
176
177
|
print(f"Refractive index at 0.55 µm: {n}")
|
|
178
|
+
# Group index and group velocity
|
|
179
|
+
n_g = bk7.compute_group_index(0.55e-6)
|
|
180
|
+
v_g = bk7.compute_group_velocity(0.55e-6)
|
|
181
|
+
print(f"Group index: {n_g:.3f}, group velocity: {v_g:.1f}")
|
|
177
182
|
|
|
178
183
|
Example
|
|
179
184
|
*******
|
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
# -*- coding: utf-8 -*-
|
|
3
3
|
|
|
4
4
|
from typing import Callable
|
|
5
|
-
from PyOptik
|
|
5
|
+
from PyOptik import units
|
|
6
6
|
import numpy
|
|
7
7
|
import warnings
|
|
8
8
|
|
|
9
9
|
|
|
10
|
-
class BaseMaterial:
|
|
10
|
+
class BaseMaterial(object):
|
|
11
11
|
def __eq__(self, other) -> bool:
|
|
12
12
|
if not isinstance(other, self.__class__):
|
|
13
13
|
return False
|
|
@@ -39,7 +39,7 @@ class BaseMaterial:
|
|
|
39
39
|
"""
|
|
40
40
|
return self.__str__()
|
|
41
41
|
|
|
42
|
-
def _check_wavelength(self, wavelength: Quantity) -> None:
|
|
42
|
+
def _check_wavelength(self, wavelength: units.Quantity) -> None:
|
|
43
43
|
"""
|
|
44
44
|
Checks if a wavelength is within the material's allowable range and raises a warning if it is not.
|
|
45
45
|
|
|
@@ -77,14 +77,61 @@ class BaseMaterial:
|
|
|
77
77
|
Wrapped version of ``func`` that accepts numerical wavelengths and
|
|
78
78
|
converts them to metre-based :class:`~PyOptik.units.Quantity` objects.
|
|
79
79
|
"""
|
|
80
|
-
def wrapper(self, wavelength: Quantity = None, *args, **kwargs):
|
|
80
|
+
def wrapper(self, wavelength: units.Quantity = None, *args, **kwargs):
|
|
81
81
|
if wavelength is None:
|
|
82
82
|
if self.wavelength_bound is None:
|
|
83
83
|
raise ValueError('Wavelength must be provided for computation.')
|
|
84
84
|
wavelength = numpy.linspace(self.wavelength_bound[0].magnitude, self.wavelength_bound[1].magnitude, 100) * self.wavelength_bound.units
|
|
85
85
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
wavelength = wavelength * meter
|
|
86
|
+
if not isinstance(wavelength, units.Quantity):
|
|
87
|
+
wavelength = wavelength * units.meter
|
|
89
88
|
return func(self, wavelength, *args, **kwargs)
|
|
90
89
|
return wrapper
|
|
90
|
+
|
|
91
|
+
@ensure_units
|
|
92
|
+
def compute_group_index(self, wavelength: units.Quantity, delta: units.Quantity = 1 * units.nanometer) -> units.Quantity:
|
|
93
|
+
"""
|
|
94
|
+
Calculate the group refractive index n_g(\u03bb).
|
|
95
|
+
The group index is defined as n_g(\u03bb) = n(\u03bb) - \u03bb * dn/d\u03bb,
|
|
96
|
+
where n(\u03bb) is the refractive index and dn/d\u03bb is the derivative of
|
|
97
|
+
the refractive index with respect to wavelength.
|
|
98
|
+
|
|
99
|
+
Parameters
|
|
100
|
+
----------
|
|
101
|
+
wavelength : units.Quantity
|
|
102
|
+
Wavelength at which to compute the group index, in metres.
|
|
103
|
+
delta : units.Quantity, optional
|
|
104
|
+
Small change in wavelength for numerical differentiation, default is 1 nanometer.
|
|
105
|
+
|
|
106
|
+
Returns
|
|
107
|
+
-------
|
|
108
|
+
units.Quantity
|
|
109
|
+
Group refractive index at the specified wavelength, in dimensionless units.
|
|
110
|
+
-------
|
|
111
|
+
units.Quantity
|
|
112
|
+
Group refractive index at the specified wavelength, in dimensionless units.
|
|
113
|
+
"""
|
|
114
|
+
n = self.compute_refractive_index(wavelength)
|
|
115
|
+
n_plus = self.compute_refractive_index(wavelength + delta)
|
|
116
|
+
dn_dlambda = (n_plus - n) / delta
|
|
117
|
+
return n - wavelength * dn_dlambda
|
|
118
|
+
|
|
119
|
+
@ensure_units
|
|
120
|
+
def compute_group_velocity(self, wavelength: units.Quantity) -> units.Quantity:
|
|
121
|
+
"""
|
|
122
|
+
Calculate the group velocity v_g(\u03bb) = c / n_g(\u03bb),
|
|
123
|
+
where c is the speed of light in vacuum and n_g(\u03bb) is the group index.
|
|
124
|
+
|
|
125
|
+
Parameters
|
|
126
|
+
----------
|
|
127
|
+
wavelength : units.Quantity
|
|
128
|
+
Wavelength at which to compute the group velocity, in metres.
|
|
129
|
+
|
|
130
|
+
Returns
|
|
131
|
+
-------
|
|
132
|
+
units.Quantity
|
|
133
|
+
Group velocity at the specified wavelength, in metres per second.
|
|
134
|
+
"""
|
|
135
|
+
ng = self.compute_group_index(wavelength)
|
|
136
|
+
c = 299792458 * units.meter / units.second
|
|
137
|
+
return c / ng
|
|
@@ -7,7 +7,7 @@ import itertools
|
|
|
7
7
|
from MPSPlots.styles import mps
|
|
8
8
|
import matplotlib.pyplot as plt
|
|
9
9
|
from typing import Optional, Union
|
|
10
|
-
from PyOptik
|
|
10
|
+
from PyOptik import units
|
|
11
11
|
from PyOptik.directories import sellmeier_data_path
|
|
12
12
|
from PyOptik.material.base_class import BaseMaterial
|
|
13
13
|
|
|
@@ -80,7 +80,7 @@ class SellmeierMaterial(BaseMaterial):
|
|
|
80
80
|
if 'wavelength_range' in parsed_yaml['DATA'][0]:
|
|
81
81
|
data_str = parsed_yaml['DATA'][0]['wavelength_range'].split()
|
|
82
82
|
|
|
83
|
-
self.wavelength_bound = numpy.array([float(val) for val in data_str]) * micrometer
|
|
83
|
+
self.wavelength_bound = numpy.array([float(val) for val in data_str]) * units.micrometer
|
|
84
84
|
|
|
85
85
|
else:
|
|
86
86
|
self.wavelength_bound = None
|
|
@@ -89,18 +89,18 @@ class SellmeierMaterial(BaseMaterial):
|
|
|
89
89
|
self.reference = parsed_yaml.get('REFERENCES', None)
|
|
90
90
|
|
|
91
91
|
@BaseMaterial.ensure_units
|
|
92
|
-
def compute_refractive_index(self, wavelength: Union[Quantity]) -> Union[float, numpy.ndarray]:
|
|
92
|
+
def compute_refractive_index(self, wavelength: Union[units.Quantity]) -> Union[float, numpy.ndarray]:
|
|
93
93
|
r"""
|
|
94
94
|
Computes the refractive index n(\u03bb) using the appropriate formula (either Formula 1, 2, 5, or 6).
|
|
95
95
|
|
|
96
96
|
Parameters
|
|
97
97
|
----------
|
|
98
|
-
wavelength : Union[Quantity]
|
|
98
|
+
wavelength : Union[units.Quantity]
|
|
99
99
|
The wavelength \u03bb in meters, can be a single float or a numpy array.
|
|
100
100
|
|
|
101
101
|
Returns
|
|
102
102
|
-------
|
|
103
|
-
Union[Quantity]
|
|
103
|
+
Union[units.Quantity]
|
|
104
104
|
The refractive index n(\u03bb) for the given wavelength or array of wavelengths.
|
|
105
105
|
|
|
106
106
|
Raises
|
|
@@ -120,25 +120,25 @@ class SellmeierMaterial(BaseMaterial):
|
|
|
120
120
|
case 1: # Formula 1 computation (standard Sellmeier)
|
|
121
121
|
n_squared = 1.0
|
|
122
122
|
for (B, C) in zipped_coefficients:
|
|
123
|
-
n_squared += (B * wavelength.to(micrometer).magnitude**2) / (wavelength.to(micrometer).magnitude**2 - C**2)
|
|
123
|
+
n_squared += (B * wavelength.to(units.micrometer).magnitude**2) / (wavelength.to(units.micrometer).magnitude**2 - C**2)
|
|
124
124
|
|
|
125
125
|
n = numpy.sqrt(n_squared)
|
|
126
126
|
|
|
127
127
|
case 2: # Formula 2 computation (extended Sellmeier)
|
|
128
128
|
n_squared = 1 + self.coefficients[0]
|
|
129
129
|
for (B, C) in zipped_coefficients:
|
|
130
|
-
n_squared += (B * wavelength.to(micrometer).magnitude**2) / (wavelength.to(micrometer).magnitude**2 - C)
|
|
130
|
+
n_squared += (B * wavelength.to(units.micrometer).magnitude**2) / (wavelength.to(units.micrometer).magnitude**2 - C)
|
|
131
131
|
n = numpy.sqrt(n_squared)
|
|
132
132
|
|
|
133
133
|
case 5: # Formula 5 computation (extended Sellmeier)
|
|
134
134
|
n = 1 + self.coefficients[0]
|
|
135
135
|
for (B, C) in zipped_coefficients:
|
|
136
|
-
n += B * wavelength.to(micrometer).magnitude**C
|
|
136
|
+
n += B * wavelength.to(units.micrometer).magnitude**C
|
|
137
137
|
|
|
138
138
|
case 6:
|
|
139
139
|
n = 1 + self.coefficients[0]
|
|
140
140
|
for (B, C) in zipped_coefficients:
|
|
141
|
-
n = B / (C - wavelength.to(micrometer).magnitude**-2)
|
|
141
|
+
n = B / (C - wavelength.to(units.micrometer).magnitude**-2)
|
|
142
142
|
|
|
143
143
|
case _:
|
|
144
144
|
raise ValueError(f"Unsupported formula type: {self.formula_type}")
|
|
@@ -146,13 +146,13 @@ class SellmeierMaterial(BaseMaterial):
|
|
|
146
146
|
return n[0] if return_as_scalar else n
|
|
147
147
|
|
|
148
148
|
@BaseMaterial.ensure_units
|
|
149
|
-
def plot(self, wavelength: Optional[Quantity] = None) -> None:
|
|
149
|
+
def plot(self, wavelength: Optional[units.Quantity] = None) -> None:
|
|
150
150
|
"""
|
|
151
151
|
Plots the refractive index as a function of wavelength over a specified range.
|
|
152
152
|
|
|
153
153
|
Parameters
|
|
154
154
|
----------
|
|
155
|
-
wavelength : Optional[Quantity]
|
|
155
|
+
wavelength : Optional[units.Quantity]
|
|
156
156
|
The range of wavelengths to plot, in meters. If not provided, the entire allowable wavelength range is used.
|
|
157
157
|
|
|
158
158
|
Raises
|
|
@@ -174,7 +174,7 @@ class SellmeierMaterial(BaseMaterial):
|
|
|
174
174
|
xlabel=r'Wavelength [$\mu$m]',
|
|
175
175
|
title=f"Refractive Index vs. Wavelength: [{self.filename}]"
|
|
176
176
|
)
|
|
177
|
-
ax.plot(wavelength.to(micrometer).magnitude, refractive_index.real, linewidth=2, label='Real Part')
|
|
177
|
+
ax.plot(wavelength.to(units.micrometer).magnitude, refractive_index.real, linewidth=2, label='Real Part')
|
|
178
178
|
ax.legend()
|
|
179
179
|
|
|
180
180
|
plt.show()
|
|
@@ -8,7 +8,7 @@ from PyOptik.directories import tabulated_data_path
|
|
|
8
8
|
from PyOptik.material.base_class import BaseMaterial
|
|
9
9
|
from MPSPlots.styles import mps
|
|
10
10
|
import matplotlib.pyplot as plt
|
|
11
|
-
from PyOptik
|
|
11
|
+
from PyOptik import units
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
|
|
@@ -82,19 +82,19 @@ class TabulatedMaterial(BaseMaterial):
|
|
|
82
82
|
data_points = parsed_yaml['DATA'][0]['data'].strip().split('\n')
|
|
83
83
|
data = numpy.array([[float(value) for value in point.split()] for point in data_points])
|
|
84
84
|
|
|
85
|
-
self.wavelength = data[:, 0] * micrometer
|
|
85
|
+
self.wavelength = data[:, 0] * units.micrometer
|
|
86
86
|
self.n_values = data[:, 1]
|
|
87
87
|
self.k_values = data[:, 2]
|
|
88
88
|
except (KeyError, IndexError, ValueError):
|
|
89
89
|
raise ValueError(f"Invalid or missing data in YAML file {file_path}")
|
|
90
90
|
|
|
91
|
-
self.wavelength_bound = [self.wavelength.min().magnitude, self.wavelength.max().magnitude] * micrometer
|
|
91
|
+
self.wavelength_bound = [self.wavelength.min().magnitude, self.wavelength.max().magnitude] * units.micrometer
|
|
92
92
|
|
|
93
93
|
# Extract reference
|
|
94
94
|
self.reference = parsed_yaml.get('REFERENCES', None)
|
|
95
95
|
|
|
96
96
|
@BaseMaterial.ensure_units
|
|
97
|
-
def compute_refractive_index(self, wavelength: Union[float, Quantity]) -> numpy.ndarray:
|
|
97
|
+
def compute_refractive_index(self, wavelength: Union[float, units.Quantity]) -> numpy.ndarray:
|
|
98
98
|
"""
|
|
99
99
|
Interpolates the refractive index (n) and absorption (k) values for the given wavelength(s).
|
|
100
100
|
|
|
@@ -119,15 +119,15 @@ class TabulatedMaterial(BaseMaterial):
|
|
|
119
119
|
|
|
120
120
|
self._check_wavelength(wavelength)
|
|
121
121
|
|
|
122
|
-
n_interp = numpy.interp(wavelength.to(meter).magnitude, self.wavelength.to(meter).magnitude, self.n_values)
|
|
123
|
-
k_interp = numpy.interp(wavelength.to(meter).magnitude, self.wavelength.to(meter).magnitude, self.k_values)
|
|
122
|
+
n_interp = numpy.interp(wavelength.to(units.meter).magnitude, self.wavelength.to(units.meter).magnitude, self.n_values)
|
|
123
|
+
k_interp = numpy.interp(wavelength.to(units.meter).magnitude, self.wavelength.to(units.meter).magnitude, self.k_values)
|
|
124
124
|
|
|
125
125
|
index = n_interp + 1j * k_interp
|
|
126
126
|
|
|
127
127
|
return index[0] if return_as_scalar else index
|
|
128
128
|
|
|
129
129
|
@BaseMaterial.ensure_units
|
|
130
|
-
def plot(self, wavelength: Optional[Quantity] = None) -> None:
|
|
130
|
+
def plot(self, wavelength: Optional[units.Quantity] = None) -> None:
|
|
131
131
|
"""
|
|
132
132
|
Plots the tabulated refractive index (n) and absorption (k) as a function of wavelength.
|
|
133
133
|
|
|
@@ -152,7 +152,7 @@ class TabulatedMaterial(BaseMaterial):
|
|
|
152
152
|
ylabel='Refractive Index (n)',
|
|
153
153
|
)
|
|
154
154
|
|
|
155
|
-
ax1.plot(wavelength.to(micrometer).magnitude, n_values, 'o-', color='tab:blue', label='n')
|
|
155
|
+
ax1.plot(wavelength.to(units.micrometer).magnitude, n_values, 'o-', color='tab:blue', label='n')
|
|
156
156
|
|
|
157
157
|
ax2 = ax1.twinx()
|
|
158
158
|
|
|
@@ -161,7 +161,7 @@ class TabulatedMaterial(BaseMaterial):
|
|
|
161
161
|
ylabel='Absorption (k)',
|
|
162
162
|
)
|
|
163
163
|
|
|
164
|
-
ax2.plot(wavelength.to(micrometer).magnitude, k_values, 'o-', color='tab:red', label='k')
|
|
164
|
+
ax2.plot(wavelength.to(units.micrometer).magnitude, k_values, 'o-', color='tab:red', label='k')
|
|
165
165
|
|
|
166
166
|
plt.show()
|
|
167
167
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: PyOptik
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.12.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
|
|
@@ -92,6 +92,7 @@ Features
|
|
|
92
92
|
- **Simulation Ready**: Ideal for light-matter interaction simulations, particularly in optics and photonics.
|
|
93
93
|
- **Simple API**: Easy-to-use API that integrates well with other Python libraries.
|
|
94
94
|
- **Open Source**: Fully open-source.
|
|
95
|
+
- **Group Index and Velocity**: Compute group index and group velocity directly from material objects.
|
|
95
96
|
|
|
96
97
|
Installation
|
|
97
98
|
************
|
|
@@ -174,6 +175,10 @@ After installing PyOptik and building the material library, you can easily acces
|
|
|
174
175
|
bk7 = MaterialBank.BK7
|
|
175
176
|
n = bk7.compute_refractive_index(0.55e-6)
|
|
176
177
|
print(f"Refractive index at 0.55 µm: {n}")
|
|
178
|
+
# Group index and group velocity
|
|
179
|
+
n_g = bk7.compute_group_index(0.55e-6)
|
|
180
|
+
v_g = bk7.compute_group_velocity(0.55e-6)
|
|
181
|
+
print(f"Group index: {n_g:.3f}, group velocity: {v_g:.1f}")
|
|
177
182
|
|
|
178
183
|
Example
|
|
179
184
|
*******
|
|
@@ -33,6 +33,7 @@ Features
|
|
|
33
33
|
- **Simulation Ready**: Ideal for light-matter interaction simulations, particularly in optics and photonics.
|
|
34
34
|
- **Simple API**: Easy-to-use API that integrates well with other Python libraries.
|
|
35
35
|
- **Open Source**: Fully open-source.
|
|
36
|
+
- **Group Index and Velocity**: Compute group index and group velocity directly from material objects.
|
|
36
37
|
|
|
37
38
|
Installation
|
|
38
39
|
************
|
|
@@ -115,6 +116,10 @@ After installing PyOptik and building the material library, you can easily acces
|
|
|
115
116
|
bk7 = MaterialBank.BK7
|
|
116
117
|
n = bk7.compute_refractive_index(0.55e-6)
|
|
117
118
|
print(f"Refractive index at 0.55 µm: {n}")
|
|
119
|
+
# Group index and group velocity
|
|
120
|
+
n_g = bk7.compute_group_index(0.55e-6)
|
|
121
|
+
v_g = bk7.compute_group_velocity(0.55e-6)
|
|
122
|
+
print(f"Group index: {n_g:.3f}, group velocity: {v_g:.1f}")
|
|
118
123
|
|
|
119
124
|
Example
|
|
120
125
|
*******
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
import pytest
|
|
3
|
+
from PyOptik import MaterialBank
|
|
4
|
+
from PyOptik.units import micrometer, meter, ureg
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def test_group_index_sellmeier():
|
|
8
|
+
bk7 = MaterialBank.BK7
|
|
9
|
+
gi = bk7.compute_group_index(0.8 * micrometer)
|
|
10
|
+
assert gi.magnitude > 0.0
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def test_group_velocity_tabulated():
|
|
14
|
+
si = MaterialBank.silicon
|
|
15
|
+
gv = si.compute_group_velocity(0.6 * micrometer)
|
|
16
|
+
c = 299792458 * meter / ureg.second
|
|
17
|
+
assert gv < c
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def test_group_index_array():
|
|
21
|
+
water = MaterialBank.water
|
|
22
|
+
wavelengths = np.linspace(0.5, 0.6, 3) * micrometer
|
|
23
|
+
gi = water.compute_group_index(wavelengths)
|
|
24
|
+
assert gi.shape == wavelengths.shape
|
|
25
|
+
|
|
26
|
+
if __name__ == "__main__":
|
|
27
|
+
pytest.main(["-W error", "-s", __file__])
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|