gratinglab 0.2.8__tar.gz → 0.3.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {gratinglab-0.2.8/src/gratinglab.egg-info → gratinglab-0.3.1}/PKG-INFO +33 -17
- {gratinglab-0.2.8 → gratinglab-0.3.1}/README.md +32 -16
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/__init__.py +1 -1
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/gui/cmethod_options.py +16 -4
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/gui/comparison.py +6 -6
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/io/ggp.py +34 -28
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/metrology/boundary/__init__.py +6 -1
- gratinglab-0.3.1/src/gratinglab/metrology/boundary/cross_section.py +873 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/metrology/config.py +0 -1
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/metrology/gui/qt/boundary_view.py +1 -13
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/metrology/settings.py +0 -2
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/metrology/wiki/reading-outputs.md +6 -4
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/metrology/workflows.py +1 -2
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/profiles.py +238 -15
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/solvers/cmethod/__init__.py +120 -4
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/solvers/cmethod/_series.py +138 -17
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/solvers/integral/__init__.py +194 -29
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/solvers/integral/_boundary.py +68 -7
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/solvers/integral/_nystrom.py +60 -11
- {gratinglab-0.2.8 → gratinglab-0.3.1/src/gratinglab.egg-info}/PKG-INFO +33 -17
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab.egg-info/SOURCES.txt +4 -1
- {gratinglab-0.2.8 → gratinglab-0.3.1}/tests/test_cmethod.py +255 -3
- {gratinglab-0.2.8 → gratinglab-0.3.1}/tests/test_ggp.py +24 -8
- {gratinglab-0.2.8 → gratinglab-0.3.1}/tests/test_gui_cmethod_options.py +35 -3
- {gratinglab-0.2.8 → gratinglab-0.3.1}/tests/test_gui_cmethod_tab.py +18 -4
- {gratinglab-0.2.8 → gratinglab-0.3.1}/tests/test_gui_compare_tab.py +12 -0
- gratinglab-0.3.1/tests/test_integral_measured_polygon.py +410 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/tests/test_measured.py +276 -1
- gratinglab-0.3.1/tests/test_trapezoidal_solvers.py +232 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/LICENSE +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/pyproject.toml +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/setup.cfg +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/checks.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/compare.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/convergence.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/geometry.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/gui/__init__.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/gui/app.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/gui/diagram.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/gui/diagram3d.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/gui/docs.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/gui/efficiency_plot.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/gui/icon.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/gui/integral_options.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/gui/launcher.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/gui/mathtext.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/gui/orders.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/gui/provenance.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/gui/qt/__init__.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/gui/qt/cmethod_tab.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/gui/qt/compare_tab.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/gui/qt/geometry_panel.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/gui/qt/geometry_tab.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/gui/qt/integral_tab.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/gui/qt/launcher.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/gui/qt/main_window.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/gui/qt/profile_plot_panel.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/gui/qt/rcwa_tab.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/gui/qt/scalar_tab.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/gui/qt/scene3d_panel.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/gui/qt/setup_tab.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/gui/qt/sizing.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/gui/qt/theming.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/gui/qt/theory_viewer.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/gui/qt/worker.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/gui/rcwa_options.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/gui/richtext.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/gui/scalar_options.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/gui/state.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/gui/theme.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/illumination.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/io/__init__.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/io/boundary.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/io/efficiency_table.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/materials/__init__.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/materials/data/SOURCES.md +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/materials/fresnel.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/materials/optical.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/materials/refractiveindex.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/measured.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/metrology/__init__.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/metrology/analyzer.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/metrology/boundary/average.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/metrology/boundary/pipeline.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/metrology/boundary/swaths.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/metrology/cli.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/metrology/core/__init__.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/metrology/core/analysis.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/metrology/core/image_flatten.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/metrology/core/orientation.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/metrology/core/processing.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/metrology/core/region_mask.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/metrology/core/scars.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/metrology/core/tip.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/metrology/data/__init__.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/metrology/data/aggregation.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/metrology/gui/__init__.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/metrology/gui/icon.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/metrology/gui/qt/__init__.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/metrology/gui/qt/app.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/metrology/gui/qt/canvas.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/metrology/gui/qt/efficiency_dialog.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/metrology/gui/qt/import_view.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/metrology/gui/qt/layout.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/metrology/gui/qt/main_window.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/metrology/gui/qt/swath_dialog.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/metrology/gui/qt/wiki_view.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/metrology/gui/qt/worker.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/metrology/gui/state.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/metrology/io/__init__.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/metrology/io/file_io.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/metrology/io/ibw.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/metrology/io/metrics.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/metrology/io/sem.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/metrology/io/spm.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/metrology/stats/__init__.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/metrology/stats/analysis.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/metrology/stats/icc.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/metrology/visualization/__init__.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/metrology/visualization/diagnostics.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/metrology/visualization/profiles.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/metrology/visualization/statistics.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/metrology/wiki/__init__.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/metrology/wiki/facet-fitting.md +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/metrology/wiki/file-formats.md +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/metrology/wiki/flattening.md +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/metrology/wiki/groove-orientation.md +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/metrology/wiki/icc-correction.md +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/metrology/wiki/overview.md +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/metrology/wiki/row-groups.md +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/metrology/wiki/scars-and-masking.md +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/metrology/wiki/swath-statistics.md +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/metrology/wiki/tip-correction.md +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/problem.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/resolution.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/result.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/solvers/__init__.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/solvers/_conditioning.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/solvers/_execution.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/solvers/base.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/solvers/cmethod/_core.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/solvers/integral/_core.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/solvers/integral/_finite.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/solvers/integral/_greens.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/solvers/integral/_kernels.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/solvers/rcwa/__init__.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/solvers/rcwa/_core.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/solvers/rcwa/_stack.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab/solvers/scalar.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab.egg-info/dependency_links.txt +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab.egg-info/entry_points.txt +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab.egg-info/requires.txt +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/src/gratinglab.egg-info/top_level.txt +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/tests/test_changelog.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/tests/test_checks.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/tests/test_compare.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/tests/test_conditioning.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/tests/test_convergence.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/tests/test_cross_method.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/tests/test_efficiency_table.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/tests/test_four_way.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/tests/test_fresnel.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/tests/test_geometry.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/tests/test_gui_diagram.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/tests/test_gui_diagram3d.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/tests/test_gui_docs.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/tests/test_gui_integral_options.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/tests/test_gui_launcher.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/tests/test_gui_mathtext.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/tests/test_gui_orders.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/tests/test_gui_provenance.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/tests/test_gui_qt.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/tests/test_gui_rcwa_options.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/tests/test_gui_richtext.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/tests/test_gui_scalar_options.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/tests/test_gui_state.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/tests/test_gui_theme.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/tests/test_illumination.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/tests/test_integral_core.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/tests/test_integral_corpus.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/tests/test_integral_finite.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/tests/test_integral_graded.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/tests/test_integral_greens.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/tests/test_integral_kernels.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/tests/test_integral_operators.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/tests/test_integral_solver.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/tests/test_io_boundary.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/tests/test_materials.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/tests/test_perturbation.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/tests/test_profiles.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/tests/test_rayleigh_anomaly.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/tests/test_rcwa.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/tests/test_rcwa_benchmarks.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/tests/test_refractiveindex.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/tests/test_resolution.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/tests/test_result.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/tests/test_scalar.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/tests/test_solver_conformance.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/tests/test_solver_execution.py +0 -0
- {gratinglab-0.2.8 → gratinglab-0.3.1}/tests/test_solver_progress.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: gratinglab
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.1
|
|
4
4
|
Summary: Open platform for diffraction grating groove metrology and efficiency analysis
|
|
5
5
|
Author: Jake McCoy, Aditi Gangadharan
|
|
6
6
|
License: BSD-3-Clause
|
|
@@ -59,9 +59,12 @@ efficiency of a grating from such a profile.
|
|
|
59
59
|
The AFM metrology is the part of the package in regular use. It measures blaze angles
|
|
60
60
|
from a scan, averages the grooves into a single profile, reports how much that profile
|
|
61
61
|
varies down the scan, corrects for the shape of the AFM tip where the data allow it,
|
|
62
|
-
and exports the averaged groove as a boundary profile. The
|
|
63
|
-
|
|
64
|
-
|
|
62
|
+
and exports the averaged groove as a boundary profile. The three rigorous
|
|
63
|
+
efficiency solvers left experimental status in 0.3, after agreeing with one
|
|
64
|
+
another and with a measured campaign whose groove was measured too (the TASTE
|
|
65
|
+
comparison in `docs/findings.md`). Their known limits are stated in the table
|
|
66
|
+
under Status, and a number from any of them is still evidence to check rather
|
|
67
|
+
than a result to rely on.
|
|
65
68
|
|
|
66
69
|
Rigorous methods for computing grating efficiency are well established, and open codes
|
|
67
70
|
exist for several of them, although each carries its own conventions and
|
|
@@ -108,12 +111,24 @@ The project is at a pre-alpha stage. The AFM metrology is the more mature of its
|
|
|
108
111
|
parts. On the efficiency side, the scalar and integral solvers, the comparison and
|
|
109
112
|
convergence harnesses and the materials layer work end to end. They are checked
|
|
110
113
|
against closed-form results, published benchmark tables, energy balance and
|
|
111
|
-
reciprocity
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
114
|
+
reciprocity. Efficiencies are absolute when a coating is named, using an optical
|
|
115
|
+
constant table supplied by the user (see Install). Since 0.2.0 two more rigorous
|
|
116
|
+
backends sit beside them, both written in-house: a rigorous coupled-wave analysis
|
|
117
|
+
(RCWA), which also models coated gratings through conformal layers, and the
|
|
118
|
+
C-method (Chandezon). Each has a tab in the efficiency window since 0.2.1.
|
|
119
|
+
|
|
120
|
+
**Since 0.3 the three rigorous solvers are no longer experimental.** The
|
|
121
|
+
criterion was use on a real problem: on the December 2018 TASTE campaign, 296
|
|
122
|
+
measured efficiencies against the grating's own AFM groove, the integral method,
|
|
123
|
+
the C-method and RCWA agree with one another to 2e-4 RMS and with the
|
|
124
|
+
measurement to 0.038, so the residual is measured not to be the solver. The two
|
|
125
|
+
defects that comparison found are dealt with. The C-method refuses a wall too
|
|
126
|
+
steep for its truncation. The integral solver's absorption on a measured polygon
|
|
127
|
+
under `conductivity="tabulated"` is fixed by `profile_smoothing="auto"`, which is
|
|
128
|
+
opt-in because it moves finely sampled profiles at long wavelengths; with the
|
|
129
|
+
default the polygon is solved as given, and the energy-balance warning names the
|
|
130
|
+
option when it fires. A tightly rounded valley remains a recorded limitation.
|
|
131
|
+
The scalar solver is an approximation and is described as one.
|
|
117
132
|
|
|
118
133
|
**Every modelling method here still needs verification**, the rigorous ones
|
|
119
134
|
included. The checks in the table below show that each method reproduces the
|
|
@@ -163,10 +178,10 @@ The method backends, in order of development:
|
|
|
163
178
|
|
|
164
179
|
| Method | Status |
|
|
165
180
|
|---|---|
|
|
166
|
-
| Scalar (Kirchhoff, x-ray blaze form) |
|
|
167
|
-
| Integral method (boundary integral, conical, undercut-capable) | experimental; perfect and finite conductivity (`conductivity="tabulated"`, Goray & Schmidt 2010), absolute efficiencies with the absorbed fraction recorded; a corner-graded mesh for profiles with corners (`corner_grading=4`, the default since 0.2.7; `0` is the equal-arc mesh), under either boundary condition; checked against published benchmark tables (Maystre & Popov; Goray & Schmidt), energy balance and reciprocity |
|
|
168
|
-
| RCWA (in-plane, conical, off-plane; Li factorization, S-matrix, layer stacks) |
|
|
169
|
-
| C-method (Chandezon) |
|
|
181
|
+
| Scalar (Kirchhoff, x-ray blaze form) | an approximation; checked against closed-form results |
|
|
182
|
+
| Integral method (boundary integral, conical, undercut-capable) | since 0.3 not experimental; perfect and finite conductivity (`conductivity="tabulated"`, Goray & Schmidt 2010), absolute efficiencies with the absorbed fraction recorded; a corner-graded mesh for profiles with corners (`corner_grading=4`, the default since 0.2.7; `0` is the equal-arc mesh), under either boundary condition; checked against published benchmark tables (Maystre & Popov; Goray & Schmidt), energy balance and reciprocity |
|
|
183
|
+
| RCWA (in-plane, conical, off-plane; Li factorization, S-matrix, layer stacks) | since 0.2.0, not experimental since 0.3; lamellar gratings exact and other profiles staircased, transmitted orders, and coatings through conformal layers (`Problem.layers`); checked against Fresnel, the Airy film formula, reciprocity, the integral solver, and published lamellar values (Granet; Lalanne & Hugonin; Gralak; Goray & Schmidt's conical tables). Not yet checked: staircase accuracy in metallic TM, and layers of a second material against an independent code |
|
|
184
|
+
| C-method (Chandezon) | since 0.2.0, not experimental since 0.3; perfect conductor in any mount, and one interface into an absorbing or lossless material, conical and coupled; checked against Goray & Schmidt's Table 3, Fresnel and the integral solver. Refuses vertical facets, undercuts, and walls too steep for the scan (the harmonics a wall needs grow with its slope times P sin γ / λ; measured against the integral solver, see the method note); converges slowly on sawtooth corners, and loses precision at high truncation on profiles deeper than about half the period, both reported in provenance. No coatings |
|
|
170
185
|
|
|
171
186
|
The comparison harness also accepts an efficiency table already computed by an
|
|
172
187
|
external program as one of its methods, so that comparison plots can be made without
|
|
@@ -458,9 +473,10 @@ derived product without prior written permission.
|
|
|
458
473
|
|
|
459
474
|
**What you do not get.** The software is provided as is, without warranty of any kind,
|
|
460
475
|
and the author is not liable for any use of it. That disclaimer carries more weight
|
|
461
|
-
here than it does for most packages, because the efficiency solvers are
|
|
462
|
-
(see Status): a number this software produces is evidence
|
|
463
|
-
another method, not a result to be relied on because a
|
|
476
|
+
here than it does for most packages, because the efficiency solvers are young and
|
|
477
|
+
validated on few gratings (see Status): a number this software produces is evidence
|
|
478
|
+
to be checked against another method, not a result to be relied on because a
|
|
479
|
+
computer printed it.
|
|
464
480
|
|
|
465
481
|
Contributions are accepted under the same licence. A pull request is taken as agreement
|
|
466
482
|
that the contribution may be distributed under BSD-3-Clause.
|
|
@@ -14,9 +14,12 @@ efficiency of a grating from such a profile.
|
|
|
14
14
|
The AFM metrology is the part of the package in regular use. It measures blaze angles
|
|
15
15
|
from a scan, averages the grooves into a single profile, reports how much that profile
|
|
16
16
|
varies down the scan, corrects for the shape of the AFM tip where the data allow it,
|
|
17
|
-
and exports the averaged groove as a boundary profile. The
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
and exports the averaged groove as a boundary profile. The three rigorous
|
|
18
|
+
efficiency solvers left experimental status in 0.3, after agreeing with one
|
|
19
|
+
another and with a measured campaign whose groove was measured too (the TASTE
|
|
20
|
+
comparison in `docs/findings.md`). Their known limits are stated in the table
|
|
21
|
+
under Status, and a number from any of them is still evidence to check rather
|
|
22
|
+
than a result to rely on.
|
|
20
23
|
|
|
21
24
|
Rigorous methods for computing grating efficiency are well established, and open codes
|
|
22
25
|
exist for several of them, although each carries its own conventions and
|
|
@@ -63,12 +66,24 @@ The project is at a pre-alpha stage. The AFM metrology is the more mature of its
|
|
|
63
66
|
parts. On the efficiency side, the scalar and integral solvers, the comparison and
|
|
64
67
|
convergence harnesses and the materials layer work end to end. They are checked
|
|
65
68
|
against closed-form results, published benchmark tables, energy balance and
|
|
66
|
-
reciprocity
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
69
|
+
reciprocity. Efficiencies are absolute when a coating is named, using an optical
|
|
70
|
+
constant table supplied by the user (see Install). Since 0.2.0 two more rigorous
|
|
71
|
+
backends sit beside them, both written in-house: a rigorous coupled-wave analysis
|
|
72
|
+
(RCWA), which also models coated gratings through conformal layers, and the
|
|
73
|
+
C-method (Chandezon). Each has a tab in the efficiency window since 0.2.1.
|
|
74
|
+
|
|
75
|
+
**Since 0.3 the three rigorous solvers are no longer experimental.** The
|
|
76
|
+
criterion was use on a real problem: on the December 2018 TASTE campaign, 296
|
|
77
|
+
measured efficiencies against the grating's own AFM groove, the integral method,
|
|
78
|
+
the C-method and RCWA agree with one another to 2e-4 RMS and with the
|
|
79
|
+
measurement to 0.038, so the residual is measured not to be the solver. The two
|
|
80
|
+
defects that comparison found are dealt with. The C-method refuses a wall too
|
|
81
|
+
steep for its truncation. The integral solver's absorption on a measured polygon
|
|
82
|
+
under `conductivity="tabulated"` is fixed by `profile_smoothing="auto"`, which is
|
|
83
|
+
opt-in because it moves finely sampled profiles at long wavelengths; with the
|
|
84
|
+
default the polygon is solved as given, and the energy-balance warning names the
|
|
85
|
+
option when it fires. A tightly rounded valley remains a recorded limitation.
|
|
86
|
+
The scalar solver is an approximation and is described as one.
|
|
72
87
|
|
|
73
88
|
**Every modelling method here still needs verification**, the rigorous ones
|
|
74
89
|
included. The checks in the table below show that each method reproduces the
|
|
@@ -118,10 +133,10 @@ The method backends, in order of development:
|
|
|
118
133
|
|
|
119
134
|
| Method | Status |
|
|
120
135
|
|---|---|
|
|
121
|
-
| Scalar (Kirchhoff, x-ray blaze form) |
|
|
122
|
-
| Integral method (boundary integral, conical, undercut-capable) | experimental; perfect and finite conductivity (`conductivity="tabulated"`, Goray & Schmidt 2010), absolute efficiencies with the absorbed fraction recorded; a corner-graded mesh for profiles with corners (`corner_grading=4`, the default since 0.2.7; `0` is the equal-arc mesh), under either boundary condition; checked against published benchmark tables (Maystre & Popov; Goray & Schmidt), energy balance and reciprocity |
|
|
123
|
-
| RCWA (in-plane, conical, off-plane; Li factorization, S-matrix, layer stacks) |
|
|
124
|
-
| C-method (Chandezon) |
|
|
136
|
+
| Scalar (Kirchhoff, x-ray blaze form) | an approximation; checked against closed-form results |
|
|
137
|
+
| Integral method (boundary integral, conical, undercut-capable) | since 0.3 not experimental; perfect and finite conductivity (`conductivity="tabulated"`, Goray & Schmidt 2010), absolute efficiencies with the absorbed fraction recorded; a corner-graded mesh for profiles with corners (`corner_grading=4`, the default since 0.2.7; `0` is the equal-arc mesh), under either boundary condition; checked against published benchmark tables (Maystre & Popov; Goray & Schmidt), energy balance and reciprocity |
|
|
138
|
+
| RCWA (in-plane, conical, off-plane; Li factorization, S-matrix, layer stacks) | since 0.2.0, not experimental since 0.3; lamellar gratings exact and other profiles staircased, transmitted orders, and coatings through conformal layers (`Problem.layers`); checked against Fresnel, the Airy film formula, reciprocity, the integral solver, and published lamellar values (Granet; Lalanne & Hugonin; Gralak; Goray & Schmidt's conical tables). Not yet checked: staircase accuracy in metallic TM, and layers of a second material against an independent code |
|
|
139
|
+
| C-method (Chandezon) | since 0.2.0, not experimental since 0.3; perfect conductor in any mount, and one interface into an absorbing or lossless material, conical and coupled; checked against Goray & Schmidt's Table 3, Fresnel and the integral solver. Refuses vertical facets, undercuts, and walls too steep for the scan (the harmonics a wall needs grow with its slope times P sin γ / λ; measured against the integral solver, see the method note); converges slowly on sawtooth corners, and loses precision at high truncation on profiles deeper than about half the period, both reported in provenance. No coatings |
|
|
125
140
|
|
|
126
141
|
The comparison harness also accepts an efficiency table already computed by an
|
|
127
142
|
external program as one of its methods, so that comparison plots can be made without
|
|
@@ -413,9 +428,10 @@ derived product without prior written permission.
|
|
|
413
428
|
|
|
414
429
|
**What you do not get.** The software is provided as is, without warranty of any kind,
|
|
415
430
|
and the author is not liable for any use of it. That disclaimer carries more weight
|
|
416
|
-
here than it does for most packages, because the efficiency solvers are
|
|
417
|
-
(see Status): a number this software produces is evidence
|
|
418
|
-
another method, not a result to be relied on because a
|
|
431
|
+
here than it does for most packages, because the efficiency solvers are young and
|
|
432
|
+
validated on few gratings (see Status): a number this software produces is evidence
|
|
433
|
+
to be checked against another method, not a result to be relied on because a
|
|
434
|
+
computer printed it.
|
|
419
435
|
|
|
420
436
|
Contributions are accepted under the same licence. A pull request is taken as agreement
|
|
421
437
|
that the contribution may be distributed under BSD-3-Clause.
|
|
@@ -22,7 +22,7 @@ from .measured import MeasuredEfficiency, MeasurementProvenance
|
|
|
22
22
|
from .resolution import ResolvingPower, resolving_power
|
|
23
23
|
from .result import EfficiencyScan, OrderEfficiency, Provenance
|
|
24
24
|
|
|
25
|
-
__version__ = "0.
|
|
25
|
+
__version__ = "0.3.1"
|
|
26
26
|
|
|
27
27
|
__all__ = [
|
|
28
28
|
"Illumination",
|
|
@@ -14,9 +14,10 @@ harmonics either side of the centre of the propagating orders.
|
|
|
14
14
|
|
|
15
15
|
The guards mirror the solver's refusals so an error lands on the field that
|
|
16
16
|
caused it instead of arriving as a ValueError from the worker thread. The
|
|
17
|
-
truncation
|
|
18
|
-
:func:`gratinglab.solvers.cmethod.truncation_floor
|
|
19
|
-
|
|
17
|
+
truncation floors are not re-derived here: they are
|
|
18
|
+
:func:`gratinglab.solvers.cmethod.truncation_floor` (the orders) and
|
|
19
|
+
:func:`~gratinglab.solvers.cmethod.wall_floor` (a steep wall), the functions
|
|
20
|
+
the solver itself applies, so the form and the solver cannot disagree.
|
|
20
21
|
"""
|
|
21
22
|
|
|
22
23
|
from __future__ import annotations
|
|
@@ -29,7 +30,8 @@ from numpy.typing import NDArray
|
|
|
29
30
|
|
|
30
31
|
from ..illumination import Illumination
|
|
31
32
|
from ..problem import Problem
|
|
32
|
-
from ..solvers.
|
|
33
|
+
from ..solvers.base import UnsupportedConfiguration
|
|
34
|
+
from ..solvers.cmethod import _MAX_TRUNCATION, truncation_floor, wall_floor
|
|
33
35
|
from .integral_options import _tabulated_index
|
|
34
36
|
from .state import FieldError, FormErrors, _number
|
|
35
37
|
|
|
@@ -119,5 +121,15 @@ def build_options(
|
|
|
119
121
|
floor = truncation_floor(problem, illumination, wavelengths, indices)
|
|
120
122
|
if truncation < floor.needed:
|
|
121
123
|
raise FormErrors((FieldError("truncation", floor.message),))
|
|
124
|
+
# A steep wall's floor goes on the field too, but only while a truncation
|
|
125
|
+
# the field accepts can meet it. Past the ceiling, or on a profile the
|
|
126
|
+
# method cannot describe at all, the solver refuses the geometry with
|
|
127
|
+
# UnsupportedConfiguration, and the tab names that refusal instead.
|
|
128
|
+
try:
|
|
129
|
+
wall = wall_floor(problem, illumination, wavelengths, indices)
|
|
130
|
+
except UnsupportedConfiguration:
|
|
131
|
+
wall = None
|
|
132
|
+
if wall is not None and truncation < wall.needed <= _MAX_TRUNCATION:
|
|
133
|
+
raise FormErrors((FieldError("truncation", wall.message),))
|
|
122
134
|
|
|
123
135
|
return {"truncation": int(truncation), "conductivity": form.conductivity}
|
|
@@ -50,13 +50,13 @@ _STYLES = ("-", "--", "-.", ":")
|
|
|
50
50
|
|
|
51
51
|
#: Closes every comparison the panel reports. Two solvers agreeing is evidence
|
|
52
52
|
#: that neither has a bug the other lacks, not that either is right: they can
|
|
53
|
-
#: share an assumption, a material table or a geometry convention.
|
|
54
|
-
#:
|
|
55
|
-
#:
|
|
53
|
+
#: share an assumption, a material table or a geometry convention. So the
|
|
54
|
+
#: panel says so where agreement is shown, dimmed because it is a fact about
|
|
55
|
+
#: the methods, not a fault in this run.
|
|
56
56
|
VERIFICATION_NOTE = (
|
|
57
|
-
"\nagreement between solvers is not verification:
|
|
58
|
-
"
|
|
59
|
-
"benchmark\n"
|
|
57
|
+
"\nagreement between solvers is not verification: they share the problem, "
|
|
58
|
+
"the optical constants and the conventions, so check against measurement "
|
|
59
|
+
"or a published benchmark\n"
|
|
60
60
|
)
|
|
61
61
|
|
|
62
62
|
#: More legend entries than this and the order legend takes a second column,
|
|
@@ -10,10 +10,8 @@ points through :meth:`~gratinglab.profiles.FromProfileData.along_dispersion`
|
|
|
10
10
|
and its inverse. The PCGrate corpus is what fixes the file's direction: the
|
|
11
11
|
TASTE run matches only with ``x`` along ``+d-hat``.
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
Default form, points only::
|
|
14
14
|
|
|
15
|
-
3 0 - Polygonal type
|
|
16
|
-
Period: 1 PSC: 1
|
|
17
15
|
0.000000 0.000000
|
|
18
16
|
0.012346 0.000808
|
|
19
17
|
...
|
|
@@ -22,19 +20,26 @@ The shared convention allows a scalar calculation and a PCGrate run to be
|
|
|
22
20
|
driven from identical geometry, which isolates the method difference from any
|
|
23
21
|
difference in assumed groove shape.
|
|
24
22
|
|
|
25
|
-
|
|
23
|
+
Four header variants exist on disk:
|
|
26
24
|
|
|
27
|
-
===================================
|
|
28
|
-
Header
|
|
29
|
-
===================================
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
``#
|
|
33
|
-
|
|
25
|
+
=================================== ==============================
|
|
26
|
+
Header Seen in
|
|
27
|
+
=================================== ==============================
|
|
28
|
+
none, points only Aditi's files, and the default
|
|
29
|
+
``3 0 - Polygonal type`` + ``Period`` most legacy files
|
|
30
|
+
``# 3 0 - Polygonal type`` (hashed) ``*_fix6/7.ggp``
|
|
31
|
+
``# X(normalized...)`` only ``*_fix{,2,3,4}.ggp``
|
|
32
|
+
=================================== ==============================
|
|
34
33
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
34
|
+
Which of these PCGrate takes was never tested here. Until 2026-10-29 this
|
|
35
|
+
docstring said only the ``3 0 - Polygonal type`` form loads, but that was
|
|
36
|
+
inferred from which legacy files sat beside PCGrate runs. Aditi, who loads
|
|
37
|
+
these into PCGrate through its border-profile import, reports that it does not
|
|
38
|
+
want a header and that she used to delete it by hand, so the writer leaves it
|
|
39
|
+
out unless asked. ``write_ggp(header=True)`` still writes the two-line form.
|
|
40
|
+
|
|
41
|
+
This module reads all four. ``np.savetxt(header=...)`` is what produces the
|
|
42
|
+
hashed variants, so it must not be used here.
|
|
38
43
|
|
|
39
44
|
This is now the only ``.ggp`` writer in the project. The metrology package
|
|
40
45
|
previously shipped a second copy, and the two were kept in agreement by a
|
|
@@ -70,7 +75,8 @@ __all__ = [
|
|
|
70
75
|
"to_profile",
|
|
71
76
|
]
|
|
72
77
|
|
|
73
|
-
#: The
|
|
78
|
+
#: The legacy two-line header, written only on request. Never prefix these
|
|
79
|
+
#: lines with ``#``.
|
|
74
80
|
GGP_HEADER = "3 0 - Polygonal type\nPeriod: 1 PSC: 1"
|
|
75
81
|
|
|
76
82
|
_CANONICAL_FIRST = "3 0 - Polygonal type"
|
|
@@ -80,9 +86,10 @@ _CANONICAL_FIRST = "3 0 - Polygonal type"
|
|
|
80
86
|
class GgpFile:
|
|
81
87
|
"""A parsed ``.ggp``, with the header provenance kept.
|
|
82
88
|
|
|
83
|
-
``format_valid``
|
|
84
|
-
|
|
85
|
-
|
|
89
|
+
``format_valid`` is False for the two hashed variants, which
|
|
90
|
+
``np.savetxt(header=...)`` produces by accident, and True for a file with
|
|
91
|
+
no header or the uncommented two-line one. It records which form a file
|
|
92
|
+
is in, not a test against PCGrate; see the module docstring.
|
|
86
93
|
"""
|
|
87
94
|
|
|
88
95
|
t: np.ndarray
|
|
@@ -187,9 +194,9 @@ def _numeric_pair(line: str) -> tuple[float, float] | None:
|
|
|
187
194
|
|
|
188
195
|
|
|
189
196
|
def _classify(header_lines: list[str]) -> tuple[str, bool]:
|
|
190
|
-
"""Name the header variant and say whether
|
|
197
|
+
"""Name the header variant and say whether it is one we write."""
|
|
191
198
|
if not header_lines:
|
|
192
|
-
return "none",
|
|
199
|
+
return "none", True
|
|
193
200
|
if header_lines[0] == _CANONICAL_FIRST:
|
|
194
201
|
return "canonical", True
|
|
195
202
|
if header_lines[0].lstrip("# ").startswith("3 0"):
|
|
@@ -219,9 +226,9 @@ def write_ggp(
|
|
|
219
226
|
t: ArrayLike | None = None,
|
|
220
227
|
y: ArrayLike | None = None,
|
|
221
228
|
fmt: str = "%f",
|
|
222
|
-
header: bool =
|
|
229
|
+
header: bool = False,
|
|
223
230
|
) -> Path:
|
|
224
|
-
"""Write a profile
|
|
231
|
+
"""Write a profile as ``x y`` points for PCGrate.
|
|
225
232
|
|
|
226
233
|
Pass either a ``profile`` or explicit ``t``/``y`` arrays. A profile is
|
|
227
234
|
reflected onto the file's ``+d-hat`` axis, the inverse of
|
|
@@ -233,12 +240,11 @@ def write_ggp(
|
|
|
233
240
|
that ends in one, as ``np.savetxt`` output does. The format is pinned by
|
|
234
241
|
``tests/test_ggp.py``; PCGrate rejects variations on it.
|
|
235
242
|
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
Reading such a file back reports ``header_variant == "none"``.
|
|
243
|
+
The points are written alone by default, with no header: Aditi reports
|
|
244
|
+
that PCGrate's border-profile import does not want one (2026-10-29).
|
|
245
|
+
``header=True`` starts the file with the two legacy :data:`GGP_HEADER`
|
|
246
|
+
lines instead. Reading a headerless file back reports
|
|
247
|
+
``header_variant == "none"``.
|
|
242
248
|
"""
|
|
243
249
|
if (profile is None) == (t is None):
|
|
244
250
|
raise ValueError("pass either a profile or both t and y, not both or neither")
|
|
@@ -3,7 +3,8 @@ Boundary profile generation for PCGrate
|
|
|
3
3
|
|
|
4
4
|
This package averages the detected grooves of an AFM scan into a single
|
|
5
5
|
representative groove, normalises it to one period, and exports it as a
|
|
6
|
-
PCGrate .ggp boundary profile.
|
|
6
|
+
PCGrate .ggp boundary profile. `trace_cross_section` does the same for an SEM
|
|
7
|
+
micrograph of a cleaved cross-section, and fits a trapezoid to it.
|
|
7
8
|
|
|
8
9
|
It shares the profile front-end (loading, groove detection, groove windowing)
|
|
9
10
|
with the blaze-angle analysis in gratinglab.metrology.core.
|
|
@@ -11,6 +12,7 @@ with the blaze-angle analysis in gratinglab.metrology.core.
|
|
|
11
12
|
|
|
12
13
|
from .pipeline import BoundaryProfile, build_boundary_profile
|
|
13
14
|
from .swaths import SwathStatistics, swath_statistics
|
|
15
|
+
from .cross_section import CrossSection, TrapezoidFit, trace_cross_section
|
|
14
16
|
from .average import (
|
|
15
17
|
flatten_endpoints,
|
|
16
18
|
average_grooves,
|
|
@@ -25,6 +27,9 @@ __all__ = [
|
|
|
25
27
|
'build_boundary_profile',
|
|
26
28
|
'SwathStatistics',
|
|
27
29
|
'swath_statistics',
|
|
30
|
+
'CrossSection',
|
|
31
|
+
'TrapezoidFit',
|
|
32
|
+
'trace_cross_section',
|
|
28
33
|
'flatten_endpoints',
|
|
29
34
|
'average_grooves',
|
|
30
35
|
'groove_residuals',
|