PyOptik 1.9.8__0-py3-none-any.whl

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 (50) hide show
  1. PyOptik/__init__.py +15 -0
  2. PyOptik/__main__.py +7 -0
  3. PyOptik/_version.py +16 -0
  4. PyOptik/data/__init__.py +0 -0
  5. PyOptik/data/sellmeier/BAK1.yml +60 -0
  6. PyOptik/data/sellmeier/BK7.yml +60 -0
  7. PyOptik/data/sellmeier/SF5.yml +54 -0
  8. PyOptik/data/sellmeier/ZBLAN.yml +10 -0
  9. PyOptik/data/sellmeier/air.yml +15 -0
  10. PyOptik/data/sellmeier/argon.yml +14 -0
  11. PyOptik/data/sellmeier/crown.yml +58 -0
  12. PyOptik/data/sellmeier/flint.yml +57 -0
  13. PyOptik/data/sellmeier/fused_silica.yml +15 -0
  14. PyOptik/data/sellmeier/germanium.yml +10 -0
  15. PyOptik/data/sellmeier/lithium_niobate.yml +10 -0
  16. PyOptik/data/sellmeier/polystyren.yml +14 -0
  17. PyOptik/data/sellmeier/silicon.yml +10 -0
  18. PyOptik/data/sellmeier/soda_lime_glass.yml +118 -0
  19. PyOptik/data/sellmeier/water.yml +14 -0
  20. PyOptik/data/tabulated/aluminium.yml +215 -0
  21. PyOptik/data/tabulated/calcium.yml +72 -0
  22. PyOptik/data/tabulated/copper.yml +58 -0
  23. PyOptik/data/tabulated/gold.yml +58 -0
  24. PyOptik/data/tabulated/iron.yml +58 -0
  25. PyOptik/data/tabulated/nickel.yml +58 -0
  26. PyOptik/data/tabulated/silver.yml +58 -0
  27. PyOptik/data/tabulated/sodium.yml +34 -0
  28. PyOptik/data/tabulated/zinc.yml +162 -0
  29. PyOptik/directories.py +44 -0
  30. PyOptik/libraries/__init__.py +0 -0
  31. PyOptik/libraries/classics.yml +28 -0
  32. PyOptik/libraries/dielectrics.yml +20 -0
  33. PyOptik/libraries/metals.yml +20 -0
  34. PyOptik/libraries/minimal.yml +9 -0
  35. PyOptik/libraries/organics.yml +11 -0
  36. PyOptik/libraries/others.yml +4 -0
  37. PyOptik/libraries/polymers.yml +8 -0
  38. PyOptik/material/__init__.py +3 -0
  39. PyOptik/material/base_class.py +90 -0
  40. PyOptik/material/sellmeier_class.py +198 -0
  41. PyOptik/material/tabulated_class.py +180 -0
  42. PyOptik/material_bank.py +466 -0
  43. PyOptik/material_type.py +9 -0
  44. PyOptik/units.py +56 -0
  45. PyOptik/utils.py +46 -0
  46. PyOptik-1.9.8.0.dist-info/LICENSE +21 -0
  47. PyOptik-1.9.8.0.dist-info/METADATA +295 -0
  48. PyOptik-1.9.8.0.dist-info/RECORD +50 -0
  49. PyOptik-1.9.8.0.dist-info/WHEEL +5 -0
  50. PyOptik-1.9.8.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,162 @@
1
+ # this file is part of refractiveindex.info database
2
+ # refractiveindex.info database is in the public domain
3
+ # copyright and related rights waived via CC0 1.0
4
+
5
+ REFERENCES: "W. S. M. Werner, K. Glantschnig, C. Ambrosch-Draxl. Optical constants and inelastic electron-scattering data for 17 elemental metals, <a href=\"https://doi.org/10.1063/1.3243762\"><i>J. Phys Chem Ref. Data</i> <b>38</b>, 1013-1092 (2009)</a>"
6
+ COMMENTS: "Experimental data: Derived from reflection electron energy-loss spectroscopy (REELS) spectra."
7
+ DATA:
8
+ - type: tabulated nk
9
+ data: |
10
+ 0.017586 0.9522 0.0688
11
+ 0.017712 0.9523 0.0693
12
+ 0.017839 0.9518 0.0704
13
+ 0.017969 0.9519 0.0709
14
+ 0.018100 0.9514 0.0720
15
+ 0.018233 0.9515 0.0725
16
+ 0.018368 0.9510 0.0736
17
+ 0.018505 0.9510 0.0741
18
+ 0.018644 0.9506 0.0752
19
+ 0.018785 0.9507 0.0763
20
+ 0.018929 0.9502 0.0768
21
+ 0.019074 0.9498 0.0779
22
+ 0.019222 0.9499 0.0790
23
+ 0.019373 0.9494 0.0800
24
+ 0.019525 0.9495 0.0811
25
+ 0.019680 0.9490 0.0817
26
+ 0.019837 0.9491 0.0827
27
+ 0.019997 0.9487 0.0838
28
+ 0.020160 0.9488 0.0848
29
+ 0.020325 0.9484 0.0859
30
+ 0.020493 0.9479 0.0870
31
+ 0.020664 0.9480 0.0881
32
+ 0.020838 0.9476 0.0892
33
+ 0.021014 0.9477 0.0902
34
+ 0.021194 0.9473 0.0913
35
+ 0.021377 0.9469 0.0924
36
+ 0.021562 0.9470 0.0940
37
+ 0.021752 0.9466 0.0951
38
+ 0.021944 0.9467 0.0961
39
+ 0.022140 0.9463 0.0972
40
+ 0.022339 0.9459 0.0988
41
+ 0.022543 0.9460 0.0999
42
+ 0.022749 0.9457 0.1015
43
+ 0.022960 0.9453 0.1026
44
+ 0.023175 0.9454 0.1037
45
+ 0.023393 0.9450 0.1053
46
+ 0.023616 0.9452 0.1069
47
+ 0.023843 0.9448 0.1080
48
+ 0.024075 0.9445 0.1096
49
+ 0.024311 0.9441 0.1112
50
+ 0.024551 0.9442 0.1123
51
+ 0.024797 0.9439 0.1139
52
+ 0.025047 0.9436 0.1155
53
+ 0.025303 0.9438 0.1171
54
+ 0.025564 0.9434 0.1187
55
+ 0.025830 0.9431 0.1203
56
+ 0.026102 0.9428 0.1220
57
+ 0.026380 0.9430 0.1235
58
+ 0.026663 0.9427 0.1252
59
+ 0.026953 0.9424 0.1268
60
+ 0.027249 0.9421 0.1290
61
+ 0.027552 0.9418 0.1306
62
+ 0.027862 0.9421 0.1322
63
+ 0.028178 0.9418 0.1343
64
+ 0.028502 0.9416 0.1365
65
+ 0.028834 0.9413 0.1381
66
+ 0.029173 0.9411 0.1403
67
+ 0.029520 0.9409 0.1424
68
+ 0.029876 0.9406 0.1441
69
+ 0.030240 0.9404 0.1462
70
+ 0.030613 0.9402 0.1484
71
+ 0.030996 0.9400 0.1505
72
+ 0.031388 0.9399 0.1532
73
+ 0.031791 0.9398 0.1554
74
+ 0.032204 0.9396 0.1575
75
+ 0.032627 0.9395 0.1602
76
+ 0.033062 0.9393 0.1623
77
+ 0.033509 0.9388 0.1651
78
+ 0.033968 0.9386 0.1673
79
+ 0.034440 0.9386 0.1699
80
+ 0.034925 0.9385 0.1726
81
+ 0.035424 0.9380 0.1754
82
+ 0.035937 0.9379 0.1781
83
+ 0.036466 0.9374 0.1808
84
+ 0.037010 0.9375 0.1840
85
+ 0.037571 0.9370 0.1868
86
+ 0.038149 0.9365 0.1901
87
+ 0.038745 0.9367 0.1932
88
+ 0.039360 0.9362 0.1960
89
+ 0.039995 0.9358 0.1993
90
+ 0.040651 0.9354 0.2026
91
+ 0.041328 0.9352 0.2064
92
+ 0.042029 0.9349 0.2097
93
+ 0.042753 0.9340 0.2131
94
+ 0.043503 0.9338 0.2169
95
+ 0.044280 0.9331 0.2208
96
+ 0.045085 0.9328 0.2240
97
+ 0.045920 0.9322 0.2280
98
+ 0.046786 0.9315 0.2319
99
+ 0.047686 0.9305 0.2364
100
+ 0.048621 0.9294 0.2405
101
+ 0.049594 0.9288 0.2444
102
+ 0.050606 0.9274 0.2491
103
+ 0.051660 0.9263 0.2531
104
+ 0.052759 0.9244 0.2580
105
+ 0.053906 0.9230 0.2627
106
+ 0.055104 0.9212 0.2676
107
+ 0.056356 0.9189 0.2726
108
+ 0.057667 0.9161 0.2778
109
+ 0.059040 0.9128 0.2832
110
+ 0.060480 0.9097 0.2891
111
+ 0.061992 0.9055 0.2949
112
+ 0.063582 0.9010 0.3013
113
+ 0.065255 0.8960 0.3080
114
+ 0.067018 0.8901 0.3151
115
+ 0.068880 0.8834 0.3232
116
+ 0.070848 0.8751 0.3314
117
+ 0.072932 0.8662 0.3411
118
+ 0.075142 0.8560 0.3517
119
+ 0.077490 0.8440 0.3637
120
+ 0.079990 0.8304 0.3775
121
+ 0.082656 0.8150 0.3939
122
+ 0.085506 0.7981 0.4135
123
+ 0.088560 0.7791 0.4370
124
+ 0.091840 0.7589 0.4658
125
+ 0.095372 0.7388 0.5008
126
+ 0.099187 0.7209 0.5438
127
+ 0.103320 0.7093 0.5942
128
+ 0.107812 0.7080 0.6483
129
+ 0.112713 0.7192 0.6966
130
+ 0.118080 0.7342 0.7273
131
+ 0.123984 0.7318 0.7400
132
+ 0.130510 0.6955 0.7541
133
+ 0.137760 0.6304 0.7971
134
+ 0.145864 0.5561 0.8811
135
+ 0.154980 0.4922 1.0066
136
+ 0.165312 0.4516 1.1670
137
+ 0.177120 0.4444 1.3570
138
+ 0.190745 0.4937 1.5648
139
+ 0.206640 0.6184 1.7124
140
+ 0.225426 0.6196 1.7464
141
+ 0.247968 0.4994 1.9795
142
+ 0.261019 0.4873 2.1720
143
+ 0.275520 0.5524 2.3940
144
+ 0.291728 0.7446 2.4832
145
+ 0.309960 0.6411 2.4613
146
+ 0.330625 0.5362 2.7034
147
+ 0.354241 0.5240 2.9907
148
+ 0.381490 0.5508 3.2986
149
+ 0.413281 0.6029 3.6376
150
+ 0.450852 0.6794 4.0209
151
+ 0.495937 0.7858 4.4636
152
+ 0.551041 0.9322 4.9850
153
+ 0.619921 1.1356 5.6116
154
+ 0.708481 1.4247 6.3811
155
+ 0.826561 1.8489 7.3486
156
+ 0.991874 2.4976 8.5981
157
+ 1.239842 3.5417 10.2617
158
+ 1.653123 5.3318 12.5605
159
+ 2.479684 8.6709 15.9470
160
+ SPECS:
161
+ n_is_absolute: true
162
+ wavelength_is_vacuum: true
PyOptik/directories.py ADDED
@@ -0,0 +1,44 @@
1
+ #!/usr/bin/env python
2
+ # -*- coding: utf-8 -*-
3
+
4
+ from pathlib import Path
5
+ import PyOptik
6
+
7
+
8
+ __all__ = [
9
+ 'root_path',
10
+ 'project_path',
11
+ 'doc_path',
12
+ 'doc_css_path',
13
+ 'logo_path'
14
+ ]
15
+
16
+ root_path = Path(PyOptik.__path__[0])
17
+
18
+ project_path = root_path.parents[0]
19
+
20
+ example_directory = root_path.joinpath('examples')
21
+
22
+ doc_path = project_path.joinpath('docs')
23
+
24
+ doc_css_path = doc_path.joinpath('source/_static/default.css')
25
+
26
+ logo_path = doc_path.joinpath('images/logo.png')
27
+
28
+ examples_path = root_path.joinpath('examples')
29
+
30
+ sellmeier_data_path = root_path.joinpath('data/sellmeier')
31
+ tabulated_data_path = root_path.joinpath('data/tabulated')
32
+
33
+ data_path = root_path.joinpath('data')
34
+
35
+ libraries_path = root_path.joinpath('libraries')
36
+
37
+
38
+ if __name__ == '__main__':
39
+ for path_name in __all__:
40
+ path = locals()[path_name]
41
+ print(path)
42
+ assert path.exists(), f"Path {path_name} do not exists"
43
+
44
+ # -
File without changes
@@ -0,0 +1,28 @@
1
+ sellmeier:
2
+ ZBLAN: https://refractiveindex.info/database/data-nk/glass/misc/ZBLAN/Gan.yml
3
+ BK7: https://refractiveindex.info/database/data-nk/glass/schott/N-BK7.yml
4
+ fused_silica: https://refractiveindex.info/database/data-nk/main/SiO2/Malitson.yml
5
+ BAK1: https://refractiveindex.info/database/data-nk/glass/schott/N-BAK1.yml
6
+ SF5: https://refractiveindex.info/database/data-nk/glass/schott/N-SF5.yml
7
+ water: https://refractiveindex.info/database/data-nk/main/H2O/Daimon-19.0C.yml
8
+ polystyren: https://refractiveindex.info/database/data-nk/organic/(C8H8)n%20-%20polystyrene/Sultanova.yml
9
+ lithium_niobate: https://refractiveindex.info/database/data-nk/main/LiNbO3/Zelmon-o.yml
10
+ germanium: https://refractiveindex.info/database/data-nk/main/Ge/Icenogle.yml
11
+ silicon: https://refractiveindex.info/database/data-nk/main/Si/Salzberg.yml
12
+ soda_lime_glass: https://refractiveindex.info/database/data-nk/glass/misc/soda-lime/Rubin-clear.yml
13
+ crown: https://refractiveindex.info/database/data-nk/glass/schott/K7.yml
14
+ flint: https://refractiveindex.info/database/data-nk/glass/schott/F2.yml
15
+ argon: https://refractiveindex.info/database/data-nk/main/Ar/Bideau-Mehu.yml
16
+ air: https://refractiveindex.info/database/data-nk/other/mixed%20gases/air/Ciddor.yml
17
+ water: https://refractiveindex.info/database/data-nk/main/H2O/Daimon-19.0C.yml
18
+
19
+ tabulated:
20
+ silver: https://refractiveindex.info/database/data-nk/main/Ag/Johnson.yml
21
+ aluminium: https://refractiveindex.info/database/data-nk/main/Al/Rakic.yml
22
+ gold: https://refractiveindex.info/database/data-nk/main/Au/Johnson.yml
23
+ calcium: https://refractiveindex.info/database/data-nk/main/Ca/Mathewson.yml
24
+ copper: https://refractiveindex.info/database/data-nk/main/Cu/Johnson.yml
25
+ iron: https://refractiveindex.info/database/data-nk/main/Fe/Johnson.yml
26
+ sodium: https://refractiveindex.info/database/data-nk/main/Na/Smith.yml
27
+ nickel: https://refractiveindex.info/database/data-nk/main/Ni/Johnson.yml
28
+ zinc: https://refractiveindex.info/database/data-nk/main/Zn/Werner.yml
@@ -0,0 +1,20 @@
1
+ sellmeier:
2
+ ZBLAN: https://refractiveindex.info/database/data-nk/glass/misc/ZBLAN/Gan.yml
3
+ BK7: https://refractiveindex.info/database/data-nk/glass/schott/N-BK7.yml
4
+ fused_silica: https://refractiveindex.info/database/data-nk/main/SiO2/Malitson.yml
5
+ BAK1: https://refractiveindex.info/database/data-nk/glass/schott/N-BAK1.yml
6
+ BAF10: https://refractiveindex.info/database/data-nk/glass/schott/N-BAF10.yml
7
+ SF5: https://refractiveindex.info/database/data-nk/glass/schott/N-SF5.yml
8
+ SF10: https://refractiveindex.info/database/data-nk/glass/schott/N-SF10.yml
9
+ SF11: https://refractiveindex.info/database/data-nk/glass/schott/N-SF11.yml
10
+ LASF9: https://refractiveindex.info/database/data-nk/glass/schott/N-LASF9.yml
11
+ FK51A: https://refractiveindex.info/database/data-nk/glass/schott/N-FK51A.yml
12
+ water: https://refractiveindex.info/database/data-nk/main/H2O/Daimon-19.0C.yml
13
+ polystyren: https://refractiveindex.info/database/data-nk/organic/(C8H8)n%20-%20polystyrene/Sultanova.yml
14
+ lithium_niobate: https://refractiveindex.info/database/data-nk/main/LiNbO3/Zelmon-o.yml
15
+ germanium: https://refractiveindex.info/database/data-nk/main/Ge/Icenogle.yml
16
+ silicon: https://refractiveindex.info/database/data-nk/main/Si/Salzberg.yml
17
+ soda_lime_glass: https://refractiveindex.info/database/data-nk/glass/misc/soda-lime/Rubin-clear.yml
18
+ crown: https://refractiveindex.info/database/data-nk/glass/schott/K7.yml
19
+ flint: https://refractiveindex.info/database/data-nk/glass/schott/F2.yml
20
+
@@ -0,0 +1,20 @@
1
+ tabulated:
2
+ silver: https://refractiveindex.info/database/data-nk/main/Ag/Johnson.yml
3
+ aluminium: https://refractiveindex.info/database/data-nk/main/Al/Rakic.yml
4
+ gold: https://refractiveindex.info/database/data-nk/main/Au/Johnson.yml
5
+ calcium: https://refractiveindex.info/database/data-nk/main/Ca/Mathewson.yml
6
+ copper: https://refractiveindex.info/database/data-nk/main/Cu/Johnson.yml
7
+ iron: https://refractiveindex.info/database/data-nk/main/Fe/Johnson.yml
8
+ sodium: https://refractiveindex.info/database/data-nk/main/Na/Smith.yml
9
+ nickel: https://refractiveindex.info/database/data-nk/main/Ni/Johnson.yml
10
+ zinc: https://refractiveindex.info/database/data-nk/main/Zn/Werner.yml
11
+ chromium: https://refractiveindex.info/database/data-nk/main/Cr/Johnson.yml
12
+ titanium: https://refractiveindex.info/database/data-nk/main/Ti/Johnson.yml
13
+ tungsten: https://refractiveindex.info/database/data-nk/main/W/Werner.yml
14
+ lead: https://refractiveindex.info/database/data-nk/main/Pb/Werner.yml
15
+ bismuth: https://refractiveindex.info/database/data-nk/main/Bi/Werner.yml
16
+ magnesium: https://refractiveindex.info/database/data-nk/main/Mg/Hagemann.yml
17
+ paladium: https://refractiveindex.info/database/data-nk/main/Pd/Johnson.yml
18
+ rhodium: https://refractiveindex.info/database/data-nk/main/Rh/Arndt.yml
19
+ vanadium: https://refractiveindex.info/database/data-nk/main/V/Johnson.yml
20
+ tantalum: https://refractiveindex.info/database/data-nk/main/Ta/Werner.yml
@@ -0,0 +1,9 @@
1
+ sellmeier:
2
+ argon: https://refractiveindex.info/database/data-nk/main/Ar/Bideau-Mehu.yml
3
+ air: https://refractiveindex.info/database/data-nk/other/mixed%20gases/air/Ciddor.yml
4
+ water: https://refractiveindex.info/database/data-nk/main/H2O/Daimon-19.0C.yml
5
+ soda_lime_glass: https://refractiveindex.info/database/data-nk/glass/misc/soda-lime/Rubin-clear.yml
6
+ silicon: https://refractiveindex.info/database/data-nk/main/Si/Salzberg.yml
7
+
8
+ tabulated:
9
+ zinc: https://refractiveindex.info/database/data-nk/main/Zn/Werner.yml
@@ -0,0 +1,11 @@
1
+ sellmeier:
2
+ ethanol: https://refractiveindex.info/database/data-nk/organic/C2H6O%20-%20ethanol/Rheims.yml
3
+ methanol: https://refractiveindex.info/database/data-nk/organic/CH4O%20-%20methanol/El-Kashef.yml
4
+ propanol: https://refractiveindex.info/database/data-nk/organic/C3H8O%20-%20propanol/Kozma.yml
5
+ ethylene: https://refractiveindex.info/database/data-nk/organic/C2H4%20-%20ethylene/Loria.yml
6
+ acetylene: https://refractiveindex.info/database/data-nk/organic/C2H2%20-%20acetylene/Loria.yml
7
+ methane: https://refractiveindex.info/database/data-nk/organic/CH4%20-%20methane/Loria.yml
8
+ ethane: https://refractiveindex.info/database/data-nk/organic/C2H6%20-%20ethane/Loria.yml
9
+ acetone: https://refractiveindex.info/database/data-nk/organic/C3H6O%20-%20acetone/Rheims.yml
10
+ glycerol: https://refractiveindex.info/database/data-nk/organic/C3H8O3%20-%20glycerol/Rheims.yml
11
+
@@ -0,0 +1,4 @@
1
+ sellmeier:
2
+ air: https://refractiveindex.info/database/data-nk/other/mixed%20gases/air/Ciddor.yml
3
+ water: https://refractiveindex.info/database/data-nk/main/H2O/Daimon-19.0C.yml
4
+ argon: https://refractiveindex.info/database/data-nk/main/Ar/Bideau-Mehu.yml
@@ -0,0 +1,8 @@
1
+ sellmeier:
2
+ polyetylene: https://refractiveindex.info/database/data-nk/organic/(C2H4)n%20-%20polyethylene/Smith.yml
3
+ pva: https://refractiveindex.info/database/data-nk/organic/(C2H3Cl)n%20-%20polyvinyl%20chloride/Zhang.yml
4
+ pvc: https://refractiveindex.info/database/data-nk/organic/(C2H4O)n%20-%20polyvinyl%20alcohol/Schnepf.yml
5
+ pdms: https://refractiveindex.info/database/data-nk/organic/(C2H6OSi)n%20-%20polydimethylsiloxane/Schneider-RTV615.yml
6
+ polystyrene: https://refractiveindex.info/database/data-nk/organic/(C8H8)n%20-%20polystyrene/Sultanova.yml
7
+ polycarbonate: https://refractiveindex.info/database/data-nk/organic/(C16H14O3)n%20-%20polycarbonate/Sultanova.yml
8
+ cellulose: https://refractiveindex.info/database/data-nk/organic/(C6H10O5)n%20-%20cellulose/Sultanova.yml
@@ -0,0 +1,3 @@
1
+ from .base_class import BaseMaterial
2
+ from .sellmeier_class import SellmeierMaterial
3
+ from .tabulated_class import TabulatedMaterial
@@ -0,0 +1,90 @@
1
+ #!/usr/bin/env python
2
+ # -*- coding: utf-8 -*-
3
+
4
+ from typing import Callable
5
+ from PyOptik.units import Quantity, meter
6
+ import numpy
7
+ import warnings
8
+
9
+
10
+ class BaseMaterial:
11
+ def __eq__(self, other) -> bool:
12
+ if not isinstance(other, self.__class__):
13
+ return False
14
+
15
+ if self.filename != other.filename:
16
+ return False
17
+
18
+ return True
19
+
20
+ def __str__(self) -> str:
21
+ """
22
+ Provides an informal string representation of the Material object.
23
+
24
+ Returns
25
+ -------
26
+ str
27
+ Informal representation of the Material object.
28
+ """
29
+ return f"Material: {self.filename}"
30
+
31
+ def __repr__(self) -> str:
32
+ """
33
+ Provides a formal string representation of the Material object, including key attributes.
34
+
35
+ Returns
36
+ -------
37
+ str
38
+ Formal representation of the Material object.
39
+ """
40
+ return self.__str__()
41
+
42
+ def _check_wavelength(self, wavelength: Quantity) -> None:
43
+ """
44
+ Checks if a wavelength is within the material's allowable range and raises a warning if it is not.
45
+
46
+ Parameters
47
+ ----------
48
+ wavelength : Quantity
49
+ The wavelength to check, in micrometers.
50
+
51
+ Raises
52
+ ------
53
+ UserWarning
54
+ If the wavelength is outside the allowable range.
55
+ """
56
+ if self.wavelength_bound is not None:
57
+ min_value, max_value = self.wavelength_bound
58
+
59
+ if numpy.any((wavelength < min_value) | (wavelength > max_value)):
60
+ warnings.warn(
61
+ f"Wavelength range goes from {wavelength.min().to_compact()} to {wavelength.max().to_compact()} "
62
+ f"which is outside the allowable range of {min_value.to_compact()} to {max_value.to_compact()} µm. "
63
+ f"[Material: {self.filename}]"
64
+ )
65
+
66
+ def ensure_units(func) -> Callable:
67
+ """
68
+ Decorator to ensure that the wavelength parameter has the correct units.
69
+
70
+ Parameters
71
+ ----------
72
+ func : Callable
73
+ The function to wrap.
74
+
75
+ Returns
76
+ -------
77
+ Callable
78
+ The wrapped function that ensures wavelength is a Quantity in meters.
79
+ """
80
+ def wrapper(self, wavelength: Quantity = None, *args, **kwargs):
81
+ if wavelength is None:
82
+ if self.wavelength_bound is None:
83
+ raise ValueError('Wavelenght must be provided for computation.')
84
+ wavelength = numpy.linspace(self.wavelength_bound[0].magnitude, self.wavelength_bound[1].magnitude, 100) * self.wavelength_bound.units
85
+
86
+ import PyOptik.units
87
+ if not isinstance(wavelength, PyOptik.units.Quantity):
88
+ wavelength = wavelength * meter
89
+ return func(self, wavelength, *args, **kwargs)
90
+ return wrapper
@@ -0,0 +1,198 @@
1
+ #!/usr/bin/env python
2
+ # -*- coding: utf-8 -*-
3
+
4
+ import yaml
5
+ import numpy
6
+ import itertools
7
+ from MPSPlots.styles import mps
8
+ import matplotlib.pyplot as plt
9
+ from pydantic.dataclasses import Field, ConfigDict, dataclass
10
+ from typing import Tuple, Optional, Union
11
+ from PyOptik.units import micrometer, Quantity
12
+ from PyOptik.directories import sellmeier_data_path
13
+ from PyOptik.material.base_class import BaseMaterial
14
+
15
+
16
+ config_dict = ConfigDict(
17
+ arbitrary_types_allowed=True
18
+ )
19
+
20
+
21
+ @dataclass(config=config_dict, slots=True, eq=False)
22
+ class SellmeierMaterial(BaseMaterial):
23
+ """
24
+ Class representing a material with Sellmeier coefficients for refractive index computation.
25
+
26
+ Attributes
27
+ ----------
28
+ filename : str
29
+ The name of the YAML file containing material properties.
30
+ coefficients : numpy.ndarray
31
+ The Sellmeier coefficients used for calculating the refractive index.
32
+ wavelength_range : Optional[Tuple[float, float]]
33
+ The allowable wavelength range for the material in micrometers.
34
+ reference : Optional[str]
35
+ Reference information for the material data.
36
+ formula_type : int
37
+ The formula type to use for refractive index calculation.
38
+ """
39
+ filename: str
40
+
41
+ coefficients: Optional[numpy.ndarray] = Field(default=None)
42
+ wavelength_bound: Optional[Tuple[float, float]] = Field(default=None)
43
+ reference: Optional[str] = Field(default=None)
44
+ formula_type: Optional[int] = Field(default=None)
45
+
46
+ def __repr__(self) -> str:
47
+ return self.__str__()
48
+
49
+ def __str__(self) -> str:
50
+ return self.filename
51
+
52
+ def __post_init__(self) -> None:
53
+ """
54
+ Post-initialization method to load coefficients, wavelength range, formula type, and reference from a YAML file.
55
+ """
56
+ self._load_coefficients()
57
+
58
+ def _load_coefficients(self) -> None:
59
+ """
60
+ Loads the Sellmeier coefficients, wavelength range, formula type, and reference from the specified YAML file.
61
+ """
62
+ file_path = sellmeier_data_path / f'{self.filename}'
63
+
64
+ if not file_path.with_suffix('.yml').exists():
65
+ raise FileNotFoundError(f"YAML file {file_path} not found.")
66
+
67
+ with file_path.with_suffix('.yml').open('r') as file:
68
+ parsed_yaml = yaml.safe_load(file)
69
+
70
+ # Extract the formula type
71
+ self.formula_type = int(parsed_yaml['DATA'][0]['type'].split()[-1])
72
+
73
+ # Extract coefficients and ensure the list has exactly 7 coefficients by padding with zeros if necessary
74
+ coefficients_str = parsed_yaml['DATA'][0]['coefficients']
75
+ coefficients = list(map(float, coefficients_str.split()))
76
+ if len(coefficients) < 7:
77
+ coefficients.extend([0.0] * (7 - len(coefficients)))
78
+ self.coefficients = numpy.array(coefficients)
79
+
80
+ # Extract wavelength range
81
+ if 'wavelength_range' in parsed_yaml['DATA'][0]:
82
+ data_str = parsed_yaml['DATA'][0]['wavelength_range'].split()
83
+
84
+ self.wavelength_bound = numpy.array([float(val) for val in data_str]) * micrometer
85
+
86
+ else:
87
+ self.wavelength_bound = None
88
+
89
+ # # Extract reference
90
+ self.reference = parsed_yaml.get('REFERENCES', None)
91
+
92
+ @BaseMaterial.ensure_units
93
+ def compute_refractive_index(self, wavelength: Union[Quantity]) -> Union[float, numpy.ndarray]:
94
+ r"""
95
+ Computes the refractive index n(\u03bb) using the appropriate formula (either Formula 1, 2, 5, or 6).
96
+
97
+ Parameters
98
+ ----------
99
+ wavelength : Union[Quantity]
100
+ The wavelength \u03bb in meters, can be a single float or a numpy array.
101
+
102
+ Returns
103
+ -------
104
+ Union[Quantity]
105
+ The refractive index n(\u03bb) for the given wavelength or array of wavelengths.
106
+
107
+ Raises
108
+ ------
109
+ ValueError
110
+ If the wavelength is outside the specified range or if an unsupported formula type is encountered.
111
+ """
112
+ return_as_scalar = numpy.isscalar(wavelength.magnitude)
113
+
114
+ wavelength = numpy.atleast_1d(wavelength)
115
+ self._check_wavelength(wavelength)
116
+
117
+ # Compute the refractive index based on the formula type
118
+ zipped_coefficients = itertools.zip_longest(*[iter(self.coefficients[1:])] * 2)
119
+
120
+ match self.formula_type:
121
+ case 1: # Formula 1 computation (standard Sellmeier)
122
+ n_squared = 1.0
123
+ for (B, C) in zipped_coefficients:
124
+ n_squared += (B * wavelength.to(micrometer).magnitude**2) / (wavelength.to(micrometer).magnitude**2 - C**2)
125
+
126
+ n = numpy.sqrt(n_squared)
127
+
128
+ case 2: # Formula 2 computation (extended Sellmeier)
129
+ n_squared = 1 + self.coefficients[0]
130
+ for (B, C) in zipped_coefficients:
131
+ n_squared += (B * wavelength.to(micrometer).magnitude**2) / (wavelength.to(micrometer).magnitude**2 - C)
132
+ n = numpy.sqrt(n_squared)
133
+
134
+ case 5: # Formula 5 computation (extended Sellmeier)
135
+ n = 1 + self.coefficients[0]
136
+ for (B, C) in zipped_coefficients:
137
+ n = B * wavelength.to(micrometer).magnitude**C
138
+
139
+ case 6:
140
+ n = 1 + self.coefficients[0]
141
+ for (B, C) in zipped_coefficients:
142
+ n = B / (C - wavelength.to(micrometer).magnitude**-2)
143
+
144
+ case _:
145
+ raise ValueError(f"Unsupported formula type: {self.formula_type}")
146
+
147
+ return n[0] if return_as_scalar else n
148
+
149
+ @BaseMaterial.ensure_units
150
+ def plot(self, wavelength: Optional[Quantity] = None) -> None:
151
+ """
152
+ Plots the refractive index as a function of wavelength over a specified range.
153
+
154
+ Parameters
155
+ ----------
156
+ wavelength : Optional[Quantity]
157
+ The range of wavelengths to plot, in meters. If not provided, the entire allowable wavelength range is used.
158
+
159
+ Raises
160
+ ------
161
+ ValueError
162
+ If the wavelength is not a 1D array or list of float values.
163
+ """
164
+ if wavelength.ndim != 1:
165
+ raise ValueError("wavelength must be a 1D array or list of float values.")
166
+
167
+ # Calculate the refractive index over the wavelength range
168
+ refractive_index = self.compute_refractive_index(wavelength)
169
+
170
+ with plt.style.context(mps):
171
+ fig, ax = plt.subplots()
172
+
173
+ ax.set(
174
+ ylabel='Refractive Index',
175
+ xlabel=r'Wavelength [$\mu$m]',
176
+ title=f"Refractive Index vs. Wavelength: [{self.filename}]"
177
+ )
178
+ ax.plot(wavelength.to(micrometer).magnitude, refractive_index.real, linewidth=2, label='Real Part')
179
+ ax.legend()
180
+
181
+ plt.show()
182
+
183
+ def print(self) -> str:
184
+ """
185
+ Provides a formal string representation of the Material object, including key attributes.
186
+
187
+ Returns
188
+ -------
189
+ str
190
+ Formal representation of the Material object.
191
+ """
192
+ return (
193
+ f"\nMaterial: '{self.filename}',\n"
194
+ f"coefficients: {self.coefficients},\n"
195
+ f"wavelength_range: {self.wavelength_bound},\n"
196
+ f"formula_type: {self.formula_type},\n"
197
+ f"reference: '{self.reference}')"
198
+ )