feat: general N-vertex Polygon shape, watertight prisms, complete ray unit tests, and streamlined wheel build - #196
Open
hstarmans wants to merge 13 commits into
Conversation
added 13 commits
September 6, 2026 12:48
…e Eigen3, and add CI - Add `pyoptools.gui.plotly_viewer` providing interactive 3D WebGL optical visualization compatible with Marimo, JupyterLab 4, and VS Code. - Update `pyoptools.gui.ipywidgets.Plot3D` with `backend="auto"`, defaulting to Plotly without crashing if pythreejs is missing. - Complete `CylindricalLens` by adding lateral closing surfaces S3..S6 for watertight optical geometry and ray propagation. - Declare `eigency` in `[build-system] requires` in `pyproject.toml` and detect via `eigency.get_includes()` in `setup.py`, allowing native build via uv/pip without requiring root or system package managers for Eigen3 headers. - Add GitHub Actions CI workflow in `.github/workflows/test.yaml` running the test suite across Linux, macOS, and Windows on Python 3.10, 3.11, and 3.12. - Add comprehensive unit tests in `tests/gui/test_plotly_viewer.py` and `tests/raytrace/component/test_component.py`. - Make `tests/test_coding_standards.py` robust against missing linter tools.
…m and DovePrism, un-skip ray tests, and streamline wheel build workflow
… lens exceptions from plotly_viewer
… update CI matrix for Python 3.13
…umpy allocations - Replace O(N log N) numpy argsort and argmin in System.propagate_ray and Component.distance/propagate with inline C-scalar tracking - Eliminate intermediate Python list allocations (dist_list, surf_list, comp_list, pi_list) - Remove obsolete numpy array and isinf imports in Cython hot loops - Remove deprecated setup_requires in setup.py to support fast incremental compilation - Tracing throughput improved by ~3.5x (~140 us/ray vs ~494 us/ray)
…cript - Track uv.lock in Git and remove from .gitignore for reproducible environments - Update AGENTS.md with modern uv workflow, Ruff/cython-lint commands, and fast incremental Cython compilation - Remove dead autopep8_cython.py script and update scripts/README.md
- Implement Component.hit_list using Eigen Vector3d/Matrix3d coordinate transformations - Transform surface hit points into component coordinate system - Resolves long-standing 'TODO: FIX THIS HITLIST TO WORK WITH EIGEN' - Add test_component_hit_list unit test in tests/raytrace/component/test_component.py
…ug prints - Remove dead stub files (gui/logutils.py and empty raytrace/config/config.py) - Remove 292 lines of legacy '# ~' Geany toggle-comment blocks across 15 files - Remove 110 lines of commented-out Python 2 / scipy.weave code from lsq.pyx - Remove 43 commented-out '# print' debug statements - Translate legacy Spanish code annotations in system.pyx and component.pyx into clean English
…ests - Fix UnboundLocalError crash in detectOpenCL() when pyopencl is not installed - Modernize detectCPUs() using os.cpu_count() or 1 instead of deprecated os.popen2 - Add test_resources.py unit test suite for detectCPUs and detectOpenCL - Fix find_aperture() grid shape bug by using complex step in np.mgrid - Fix chief_ray_search() IndexError when rays miss aperture detector - Unskip and activate passing unit tests: test_paraxial_location, test_find_aperture, and test_find_ppp
…le proxies - Fix Sphinx autodoc crash on dynamic catalog modules (library, material) by preserving standard module attributes (__name__, __doc__, etc.) and ignoring private/dunder attributes in __getattr__ - Add nbsphinx_execute = 'never' in doc/conf.py to prevent doc build crashes when Jupyter kernel is unavailable - Update doc/install.rst with modern uv install commands (uv add / uv pip) and optional visualization packages - Update doc/development.rst with uv sync, in-place Cython compilation, pytest, ruff, cython-lint, and local doc build instructions - Update README.md with feature overview, quick installation, working quickstart raytrace example, and docs link - Update CONTRIBUTING.md with Python >= 3.10 requirement and uv developer setup
Fixes NameError when doc notebooks and user scripts use 'from pyoptools.all import *' and subsequently access vendor catalog parts via 'library' (e.g. library.Edmund.get()).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Hi @ramezquitao,
Following up on PR #1 (#195), this pull request addresses several open TODOs and completes pending unit tests in
pyoptools:1. Arbitrary N-Vertex
PolygonAperture Shapepyoptools.raytrace.shape.Polygonfrom a 3-vertex triangle placeholder into a true general N-vertex polygonal aperture.hit_cy(Vector3d &point) noexcept nogil) with zero heap allocations during ray hit tests.limits()and 2D mesh grid sampling inpointlist().__reduce__support for pickling.2. Watertight
PentaPrismandDovePrismPentaPrism: Added lateral closing surfacesS6(top) andS7(bottom) using a 5-vertex polygon matching the prism geometry.DovePrism: Added lateral closing surfacesS5(top) andS6(bottom) using a 4-vertex trapezoid polygon.3. Completed Pending Ray Tests
tests/raytrace/ray/test_ray.py:test_get_final_rays(leaf ray extraction with zero/nonzero intensity filtering)test_add_child(parent-child ray tree linkages and ordering)test_optical_path_parent(accumulated optical path length from root)test_optical_path(ray optical path calculation)4. New Unit Tests
tests/raytrace/shape/test_shapes.py: 6 tests forPolygon(validation, triangles, trapezoids, pentagons, pointlist, pickling).tests/raytrace/component/test_component.py: Unit tests forPentaPrism(90° deviation and top surface hit) andDovePrism(top surface hit).5. Streamlined Wheel Build Workflow
.github/workflows/build.yamlto remove manual OS package manager installations for Eigen, taking full advantage of the nativeeigencydependency declared in[build-system] requires.6. Modernized Coding Standards with Ruff & Cython-Lint
pycodestyle,pep8, andautopep8with Ruff (ruff>=0.8.0) for fast Python linting and formatting.cython-lint(cython-lint>=0.18.0) for Cython AST inspection (.pyx/.pxd).compound_lens.py/cube.pyandcomp_lib.pyby switching to relative imports.ruff check --fixandruff format.7. Eliminated Python 2 Syntax & Legacy Dict Methods in Cython
raise Exc, msgacrosssurface.pyxandsystem.pyx..iteritems(),.itervalues(), and.iterkeys()to standard Python 3.items(),.values(), and.keys()inpicklable.pyx,component.pyx, andsystem.pyx(with backward compatibility aliases preserved).8. System Ray-Marching Inner Loop Performance (~3.5× Speedup)
asarray(dist_list).argsort()inSystem.propagate_raywith single-pass O(N) inline C scalar tracking of the two nearest components (comp0,comp1,d0,d1).asarray(dist_list).argmin()inComponent.distance,Component.propagate, andSystem.distancewith inline C double distance tracking (min_d = INFINITY,min_surf,min_pi).array(dist_list)andall(npisinf(...))with an immediate scalar checkisinf(d0).dist_list,surf_list,comp_list, andpi_listinpropagate_ray.plist.setup_requires=["setuptools_scm", "Cython", "eigency"]fromsetup.pythat forced Setuptools to attempt isolated wheel downloads.python setup.py build_ext --inplace) now finishes in ~1.2 s to 11 s.9. Tracked
uv.lock& Modernized Developer Guidelines (AGENTS.md)Tracked
uv.lockin Version Control:uv.lockfrom.gitignorein line with standard Astral / modern Python library best practices.uv buildorpip install pyoptools), packaging backends usepyproject.tomldependency ranges—end users on PyPI are never pinned to the lockfile. Committinguv.lockensures maintainers, contributors, and CI runners have 100% reproducible environments and eliminates unexpected CI breakage from upstream patch releases.Updated
AGENTS.md:uvworkflows (uv run python setup.py build_ext --inplace,uv run pytest,uv run ruff check).pip installand deadautopep8scripts.NO COMMENTSrule) in favor of clear code documentation practices.10. Resolved
Component.hit_listwith Eigen Coordinate TransformationsImplemented Long-Standing TODO: Implemented the
hit_listproperty inComponent(component.pyx) to aggregate hit points from all internal component surfaces.Native Eigen Acceleration: Evaluated local surface intersection hits in C++ and transformed coordinates into the component coordinate system using Eigen
Vector3dandMatrix3drotation matrices.New Unit Test: Added
test_component_hit_listintests/raytrace/component/test_component.py, verifying multi-surface coordinate transformations on double-convex spherical lenses.11. Codebase Cleanup: Dead Stubs, Legacy Comments & Obsolete C Code
pyoptools/gui/logutils.pyand 0-byte filepyoptools/raytrace/config/config.py.# ~Geany comment blocks across 15 files.scipy.weaveinline C code frompyoptools/misc/lsq/lsq.pyx.# printstatements and translated legacy Spanish developer comments into clean English acrosscomponent.pyx,system.pyx, andtaylor_poly.pyx. All intentional domain/physics TODOs were preserved.12. Bug Fixes in Calculation & Resource Detection
detectOpenCL()Crash Fix: ResolvedUnboundLocalError: local variable 'cl' referenced before assignmentinpyoptools/misc/resources/resources.pyxwhenpyopenclis not installed by safely checking imports.detectCPUs()Modernization: Replaced Python 2's removedos.popen2("sysctl -n hw.ncpu")with modernos.cpu_count() or 1.find_aperture()Grid Dimension Fix: Inpyoptools/raytrace/calc/calc.py, replaced floating-point step size indexing innp.mgridwith complex step countscomplex(0, tx)andcomplex(0, ty), guaranteeing exact(tx, ty)output array dimensions without floating-point accumulation rounding errors.chief_ray_search()Graceful Error Handling: Caught(ValueError, IndexError)onccds.hit_list[0]incalc.pyso candidate rays that miss the aperture detector correctly assigndist = infrather than crashing unhandled.test_paraxial_location,test_find_aperture, andtest_find_pppintests/raytrace/calc/test_calc.py.tests/misc/resources/test_resources.pyfor CPU and OpenCL detection.13. Documentation Build Fixes, Modernization & Quickstart
sphinxcontrib.apidoc/autodoccaused by dynamic module replacements inlibrary.pyandmaterial.py. Added attribute guards (if name.startswith("_"): raise AttributeError(...)) and populated standard module metadata (__name__,__doc__,__file__,__package__) on replacement instances insys.modules.nbsphinx_execute = 'never'indoc/conf.pyto prevent headless documentation build timeouts on live Jupyter kernels while fully rendering all 11 notebooks into static HTML.sphinx-build -b html doc doc/_build/html) now builds completely with 0 errors.doc/install.rst: Added recommendeduvcommands (uv add pyoptools/uv pip install pyoptools), Python 3.10–3.13 requirements, optional visualization dependencies (jupyterlab,plotly), and source build instructions.doc/development.rst: Documented local setup withuv sync, fast in-place compilation, pytest,ruff,cython-lint, and local Sphinx build commands.README.md: Expanded from a 20-line stub into a comprehensive overview with key features, quick installation, a verified 15-line Quickstart raytrace code snippet, and links to documentation.CONTRIBUTING.md: Updated Python prerequisites to>= 3.10and addeduvworkflows.14. Export
libraryinpyoptools.all& Verified Doc Notebookslibrary: Addedfrom pyoptools.raytrace.library import *topyoptools/all.pyso user scripts and notebooks can directly access vendor catalogs (library.Edmund,library.Thorlabs).doc/notebooks/basic/(Autocollimator.ipynb,Binocular.ipynb,GeomWF.ipynb,SimpleRayTraces.ipynb, etc.), ensuring all ray-tracing math, component constructors, and catalog lookups run cleanly.