-
Notifications
You must be signed in to change notification settings - Fork 1
Unify order2res Earth model with the spec-page sphere (R=6371.0088) #126
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -11,32 +11,39 @@ | |
| - Tests focus on consistency, determinism, and structural validation | ||
| """ | ||
|
|
||
| import math | ||
|
|
||
| import pytest | ||
| import numpy as np | ||
| from numpy.testing import assert_array_equal, assert_allclose | ||
|
|
||
| from mortie import tools | ||
|
|
||
|
|
||
| def _sphere_res(order): | ||
| """Reference RMS cell spacing (km): sqrt of the equal-area cell area.""" | ||
| R = tools.EARTH_RADIUS_KM | ||
| return math.sqrt(4 * math.pi * R**2 / (12 * 4**order)) | ||
|
|
||
|
|
||
| class TestOrder2Res: | ||
| """Test order to resolution conversion""" | ||
|
|
||
| def test_order2res_basic(self): | ||
| """Test basic order to resolution calculations""" | ||
| # Order 0 should be largest resolution | ||
| # Order 0 is the RMS cell spacing on the unified HEALPix sphere. | ||
| res0 = tools.order2res(0) | ||
| assert_allclose(res0, 111 * 58.6323, rtol=1e-10) | ||
| assert_allclose(res0, _sphere_res(0), rtol=1e-10) | ||
|
|
||
| # Order 1 should be half of order 0 | ||
| # Each order halves the cell scale (area drops by 4). | ||
| res1 = tools.order2res(1) | ||
| assert_allclose(res1, res0 / 2.0, rtol=1e-10) | ||
|
|
||
| def test_order2res_range(self): | ||
| """Test full range of valid orders""" | ||
| """Test full range of valid orders against the sphere formula""" | ||
| for order in range(20): | ||
| res = tools.order2res(order) | ||
| expected = 111 * 58.6323 * (0.5 ** order) | ||
| assert_allclose(res, expected, rtol=1e-10) | ||
| assert_allclose(res, _sphere_res(order), rtol=1e-10) | ||
|
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🤖 from Claude (review) Self-referential pin (acceptable, but worth one literal anchor). Both Coverage isn't actually lost overall — Generated by Claude Code |
||
|
|
||
| def test_order2res_decreasing(self): | ||
| """Test that resolution decreases with order""" | ||
|
|
@@ -72,12 +79,12 @@ def test_unit_ladder_km_m_cm(self, capsys): | |
| tools.res2display() | ||
| lines = capsys.readouterr().out.strip().split('\n') | ||
| by_order = {int(line.rsplit(' ', 1)[1]): line for line in lines} | ||
| # order 12 = 1.589 km, order 13 = 794.456 m (the issue's examples) | ||
| assert by_order[12] == '1.589 km at tessellation order 12' | ||
| assert by_order[13] == '794.456 m at tessellation order 13' | ||
| # order 12 = 1.592 km, order 13 = 795.852 m (unified sphere, issue #119) | ||
| assert by_order[12] == '1.592 km at tessellation order 12' | ||
| assert by_order[13] == '795.852 m at tessellation order 13' | ||
| # finest orders drop to cm rather than tiny km/m fractions | ||
| assert by_order[25] == '19.396 cm at tessellation order 25' | ||
| assert by_order[29] == '1.212 cm at tessellation order 29' | ||
| assert by_order[25] == '19.43 cm at tessellation order 25' | ||
| assert by_order[29] == '1.214 cm at tessellation order 29' | ||
|
|
||
| def test_rounds_within_bracket(self, capsys): | ||
| """Values are rounded to three decimals inside the chosen unit""" | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,6 +7,11 @@ | |
| from . import _healpix as hp | ||
| from . import _rustie | ||
|
|
||
| # Mean Earth radius (km), the exact HEALPix sphere the spec page's resolution | ||
| # table (docs/specification.md §3) derives from. order2res is the RMS cell | ||
| # spacing on this sphere; unified with the page in issue #119. | ||
| EARTH_RADIUS_KM = 6371.0088 | ||
|
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🤖 from Claude (review) Non-blocking observation (out of scope for this diff). The module now carries two Earth-radius constants: Generated by Claude Code |
||
|
|
||
| # Rust-native geo2mort (uses healpix crate, no Python HEALPix backend) | ||
| _rust_geo2mort = _rustie.rust_geo2mort | ||
| # Packed-word kernel bridge: morton <-> HEALPix NESTED (vectorized). | ||
|
|
@@ -20,8 +25,16 @@ | |
|
|
||
|
|
||
| def order2res(order): | ||
| res = 111 * 58.6323 * .5**order | ||
| return res | ||
| """Approximate cell scale (km) at a HEALPix tessellation ``order``. | ||
|
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🤖 from Claude (review) Nit (wording): the summary line calls this "Approximate cell scale", but the body — correctly — says it is the exact RMS cell spacing on the equal-area HEALPix sphere ( Generated by Claude Code |
||
|
|
||
| The exact RMS cell spacing on the mean-radius HEALPix sphere: every | ||
| order-k cell has identical area ``4*pi*R**2 / (12 * 4**order)`` (HEALPix is | ||
| equal-area), and the cell scale is the square root of that area. Derived | ||
| from :data:`EARTH_RADIUS_KM` so code and the spec page (§3) share one Earth | ||
| model (issue #119). | ||
| """ | ||
| area = 4 * np.pi * EARTH_RADIUS_KM**2 / (12 * 4**order) # km2 | ||
| return float(np.sqrt(area)) | ||
|
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🤖 from Claude (review) Minor behavioral narrowing: Generated by Claude Code |
||
|
|
||
|
|
||
| def res2display(max_order=MAX_ORDER): | ||
|
|
@@ -32,7 +45,7 @@ def res2display(max_order=MAX_ORDER): | |
| Each resolution is rendered in the largest sensible unit -- km at coarse | ||
| orders, m once it drops below 1 km, cm once it drops below 1 m -- and | ||
| rounded to three decimals within that bracket, so fine orders read | ||
| naturally (e.g. order 12 -> ``1.589 km``, order 13 -> ``794.456 m``) | ||
| naturally (e.g. order 12 -> ``1.592 km``, order 13 -> ``795.852 m``) | ||
| rather than as tiny km fractions. | ||
|
|
||
| ``max_order`` must lie in 0..MAX_ORDER, the order range the packed-u64 | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Import block is un-sorted or un-formatted
mortie/mortie/tests/test_tools.py
Lines 14 to 20 in dbba806