Skip to content

Add MaxDeterminantGrid with full AngularGrid and AtomGrid integration#297

Open
alok-108 wants to merge 7 commits intotheochem:masterfrom
alok-108:feature/max-det-spherical-grid
Open

Add MaxDeterminantGrid with full AngularGrid and AtomGrid integration#297
alok-108 wants to merge 7 commits intotheochem:masterfrom
alok-108:feature/max-det-spherical-grid

Conversation

@alok-108
Copy link
Copy Markdown

@alok-108 alok-108 commented Mar 26, 2026

Implemented MaxDeterminantGrid using maximum determinant (Fekete) points for spherical integration with positive weights and improved numerical stability.

Key Features

  • Integrated with AngularGrid and AtomGrid
    • Supports both degree and size initialization
    • Uses precomputed datasets

Validation

  • Verified sum weights = 4pi
    • Constant integration returns 4pi
    • Spherical harmonics validated across full range
    • All tests pass (79/79)

Fixes

  • Corrected spherical harmonic test coverage
    • Fixed Sphinx math formatting
    • Added notebook integration via .nblink

Notes

All tests and documentation build successfully in a clean environment.

Updates (pre-review cleanup):

  • Removed debug artifacts (results.txt, output.txt) and auto-generated _version.py from tracked files
    • Fixed hardcoded local path in fetch_maxdet_data.py
    • Added __all__ to max_det.py, removed dead MAXDET_CACHE from angular.py
    • Consolidated filesystem scanning into single _get_available_degrees() method
    • Normalized weight convention: raw weights stored internally, 4pi factor applied consistently at AngularGrid level

@alok-108
Copy link
Copy Markdown
Author

Hi @PaulWAyers,

Would really appreciate your review whenever you get time. Happy to make any changes if needed!

1 similar comment
@alok-108
Copy link
Copy Markdown
Author

Hi @PaulWAyers,

Would really appreciate your review whenever you get time. Happy to make any changes if needed!

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new maximum-determinant (Fekete) spherical quadrature (MaxDeterminantGrid) and wires it into AngularGrid/AtomGrid, with bundled precomputed datasets and docs/examples.

Changes:

  • Introduces MaxDeterminantGrid with loading of packaged .npz point/weight datasets and a convenience integrate() API.
  • Extends AngularGrid/AtomGrid to support method="maxdet" and updates related tests.
  • Adds packaged maxdet datasets, a fetch script, and documentation/notebook integration.

Reviewed changes

Copilot reviewed 13 out of 26 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/grid/max_det.py New MaxDeterminantGrid implementation and dataset loader.
src/grid/angular.py Adds method="maxdet" support and routes loading/degree-size mapping accordingly.
src/grid/atomgrid.py Updates docstrings to include maxdet as an available angular method.
src/grid/init.py Re-exports maxdet module from package root.
src/grid/tests/test_maxdet.py New unit tests for maxdet weights and integration behavior.
src/grid/tests/test_atomgrid.py Extends existing AtomGrid tests to run with method="maxdet".
src/grid/tests/test_angular.py Fixes/adjusts spherical harmonic indexing and assertions in tests.
src/grid/data/max_det/init.py Marks maxdet data directory as a package.
src/grid/data/max_det/maxdet_1_4.npz Adds precomputed maxdet dataset (degree 1).
src/grid/data/max_det/maxdet_2_9.npz Adds precomputed maxdet dataset (degree 2).
src/grid/data/max_det/maxdet_3_16.npz Adds precomputed maxdet dataset (degree 3).
src/grid/data/max_det/maxdet_4_25.npz Adds precomputed maxdet dataset (degree 4).
src/grid/data/max_det/maxdet_5_36.npz Adds precomputed maxdet dataset (degree 5).
src/grid/data/max_det/maxdet_10_121.npz Adds precomputed maxdet dataset (degree 10).
src/grid/data/max_det/maxdet_20_441.npz Adds precomputed maxdet dataset (degree 20).
src/grid/data/max_det/maxdet_30_961.npz Adds precomputed maxdet dataset (degree 30).
src/grid/data/max_det/maxdet_40_1681.npz Adds precomputed maxdet dataset (degree 40).
scripts/fetch_maxdet_data.py Script to download and convert upstream maxdet datasets into .npz.
examples/max_det_integration.ipynb Example notebook demonstrating maxdet spherical integration.
doc/notebooks/max_det_integration.nblink Links the example notebook into the Sphinx docs build.
doc/index.rst Adds the maxdet notebook to the documentation toctree.
MANIFEST.in Ensures maxdet .npz files are included in source distributions.
.gitignore Ignores debug/output artifacts and autogenerated version file.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/grid/angular.py
Comment thread src/grid/max_det.py Outdated
The integral of the function/arrays over the unit sphere.
"""
if len(args) == 1 and callable(args[0]):
return 4 * np.pi * np.sum(args[0](self.points) * self.weights)
Copy link

Copilot AI Apr 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the callable branch, integrate() bypasses Grid.integrate()'s shape/type checks and uses np.sum(args[0](self.points) * self.weights). If the callable returns a scalar or an array with shape (N,1)/(1,N), NumPy broadcasting can produce an incorrect result without raising. Consider coercing the result to np.asarray, validating it is 1-D with shape (self.size,), and then using the same einsum/integration path as Grid.integrate().

Suggested change
return 4 * np.pi * np.sum(args[0](self.points) * self.weights)
values = np.asarray(args[0](self.points))
if values.ndim != 1 or values.shape != (self.size,):
raise ValueError(
f"Callable passed to integrate must return a 1-D array with shape {(self.size,)}, "
f"got shape {values.shape}."
)
return 4 * np.pi * super().integrate(values)

Copilot uses AI. Check for mistakes.
Comment thread src/grid/tests/test_maxdet.py Outdated
import numpy as np
import pytest
from grid.max_det import MaxDeterminantGrid
from grid.utils import generate_real_spherical_harmonics, convert_cart_to_sph
Copy link

Copilot AI Apr 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

convert_cart_to_sph is imported but never used in this test file. Removing the unused import will keep the test module clean and avoid linting issues in stricter environments.

Suggested change
from grid.utils import generate_real_spherical_harmonics, convert_cart_to_sph
from grid.utils import generate_real_spherical_harmonics

Copilot uses AI. Check for mistakes.
@alok-108
Copy link
Copy Markdown
Author

@PaulWAyers @marco-2023 @FarnazH

I fixed the three things the Copilot code review pointed out. Here’s what I changed:

  1. Checking maxdet values early
    In the AngularGrid._get_degree_and_size method, I now check the degree and size numbers right at the start. This way, wrong values for maxdet are caught immediately for all grid types, instead of being quietly accepted.
    I also updated the test test_errors_and_warnings so it now expects a TypeError (an error about wrong data type).

  2. Checking the shape of custom function results
    When MaxDeterminantGrid.integrate uses a custom function, the output is turned into a one‑dimensional list of numbers. Then I check that its length matches self.size. After that, the normal integrate method handles it safely, without any hidden size‑mismatch problems.

  3. Removed an unused import
    I deleted the line from grid.utils import convert_cart_to_sph in test_maxdet.py because it wasn’t being used.

All the tests in test_angular.py and test_maxdet.py still pass on my computer. The changes are in commit 7cc7b95 and should show up here now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants