|
| 1 | +import pytest |
| 2 | +import yaml |
| 3 | +from skymap_convert.utils import ( |
| 4 | + get_quad_from_patch_id, |
| 5 | + get_quad_from_tract_id, |
| 6 | + quads_are_equiv, |
| 7 | +) |
| 8 | +from tqdm import tqdm |
| 9 | + |
| 10 | +TRACT_SAMPLES = [1, 250, 1899] |
| 11 | +PATCH_SAMPLES = [0, 42, 99] |
| 12 | + |
| 13 | + |
| 14 | +@pytest.mark.longrun |
| 15 | +def test_writer_creates_expected_files(lsst_skymap, written_skymap_data): |
| 16 | + """Test that ConvertedSkymapWriter creates all expected output files. |
| 17 | +
|
| 18 | + Parameters |
| 19 | + ---------- |
| 20 | + lsst_skymap : lsst.skymap.SkyMap |
| 21 | + The original LSST skymap object to write. |
| 22 | + written_skymap_data : dict |
| 23 | + Fixture providing written skymap data with output_dir, skymap_name, and reader. |
| 24 | +
|
| 25 | + Notes |
| 26 | + ----- |
| 27 | + Verifies that: |
| 28 | + - All expected files (metadata.yaml, tracts.npy, patches.npy.gz) are created |
| 29 | + - No temporary files are left behind |
| 30 | + - Files have non-zero size |
| 31 | + """ |
| 32 | + pytest.importorskip("lsst.skymap") |
| 33 | + pytest.importorskip("lsst.sphgeom") |
| 34 | + |
| 35 | + output_dir = written_skymap_data["output_dir"] |
| 36 | + skymap_name = written_skymap_data["skymap_name"] |
| 37 | + |
| 38 | + # Check expected files exist |
| 39 | + assert (output_dir / "metadata.yaml").exists() |
| 40 | + assert (output_dir / "tracts.npy").exists() |
| 41 | + assert (output_dir / "patches.npy.gz").exists() |
| 42 | + |
| 43 | + # Check temporary files are cleaned up |
| 44 | + assert not (output_dir / "patches.npy").exists() |
| 45 | + |
| 46 | + # Check files have content |
| 47 | + assert (output_dir / "metadata.yaml").stat().st_size > 0 |
| 48 | + assert (output_dir / "tracts.npy").stat().st_size > 0 |
| 49 | + assert (output_dir / "patches.npy.gz").stat().st_size > 0 |
| 50 | + |
| 51 | + # Load and check metadata |
| 52 | + with open(output_dir / "metadata.yaml", "r") as f: |
| 53 | + metadata = yaml.safe_load(f) |
| 54 | + |
| 55 | + assert metadata["name"] == skymap_name |
| 56 | + assert metadata["n_tracts"] == len(lsst_skymap) |
| 57 | + assert metadata["n_patches_per_tract"] == 100 |
| 58 | + assert metadata["format_version"] == 1 |
| 59 | + assert "generated" in metadata |
| 60 | + assert metadata["generated"].endswith("Z") # ISO format with UTC |
| 61 | + |
| 62 | + |
| 63 | +@pytest.mark.longrun |
| 64 | +def test_writer_sample_tracts(lsst_skymap, written_skymap_data): |
| 65 | + """Test complete round-trip: write with ConvertedSkymapWriter, read with ConvertedSkymapReader. |
| 66 | +
|
| 67 | + Parameters |
| 68 | + ---------- |
| 69 | + lsst_skymap : lsst.skymap.SkyMap |
| 70 | + The original LSST skymap object. |
| 71 | + written_skymap_data : dict |
| 72 | + Fixture providing written skymap data with output_dir, skymap_name, and reader. |
| 73 | +
|
| 74 | + Notes |
| 75 | + ----- |
| 76 | + Verifies that data written by ConvertedSkymapWriter can be correctly |
| 77 | + read by ConvertedSkymapReader and produces identical results. |
| 78 | + """ |
| 79 | + pytest.importorskip("lsst.skymap") |
| 80 | + pytest.importorskip("lsst.sphgeom") |
| 81 | + |
| 82 | + reader = written_skymap_data["reader"] |
| 83 | + skymap_name = written_skymap_data["skymap_name"] |
| 84 | + |
| 85 | + # Verify metadata matches |
| 86 | + assert reader.metadata["name"] == skymap_name |
| 87 | + assert reader.n_tracts == len(lsst_skymap) |
| 88 | + assert reader.n_patches_per_tract == 100 |
| 89 | + |
| 90 | + # Verify a few sample geometries match original |
| 91 | + for tract_id in TRACT_SAMPLES: |
| 92 | + original_tract = get_quad_from_tract_id(lsst_skymap, tract_id, inner=True) |
| 93 | + round_trip_tract = reader.get_tract_vertices(tract_id) |
| 94 | + |
| 95 | + assert quads_are_equiv(original_tract, round_trip_tract), f"Round-trip failed for tract {tract_id}" |
| 96 | + |
| 97 | + for patch_id in PATCH_SAMPLES: |
| 98 | + original_patch = get_quad_from_patch_id(lsst_skymap, tract_id, patch_id) |
| 99 | + round_trip_patch = reader.get_patch_vertices(tract_id, patch_id) |
| 100 | + |
| 101 | + assert quads_are_equiv( |
| 102 | + original_patch, round_trip_patch |
| 103 | + ), f"Round-trip failed for patch {patch_id} in tract {tract_id}" |
| 104 | + |
| 105 | + |
| 106 | +@pytest.mark.longrun |
| 107 | +def test_writer_full_skymap_integrity(lsst_skymap, written_skymap_data): |
| 108 | + """Comprehensive test that writer preserves all tract and patch geometries. |
| 109 | +
|
| 110 | + Parameters |
| 111 | + ---------- |
| 112 | + lsst_skymap : lsst.skymap.SkyMap |
| 113 | + The original LSST skymap object. |
| 114 | + written_skymap_data : dict |
| 115 | + Fixture providing written skymap data with output_dir, skymap_name, and reader. |
| 116 | +
|
| 117 | + Notes |
| 118 | + ----- |
| 119 | + This is a comprehensive test that verifies every tract and patch geometry |
| 120 | + is preserved correctly using the session-scoped written skymap data. |
| 121 | + """ |
| 122 | + if True: |
| 123 | + pytest.skip( |
| 124 | + "Skipping full integrity test as it takes an exceptionally long time to run. " |
| 125 | + "Recommend running periodically, especially after major changes to the writer. " |
| 126 | + "To run, manually remove the branching logic in the code of the test." |
| 127 | + ) |
| 128 | + else: |
| 129 | + pytest.importorskip("lsst.skymap") |
| 130 | + pytest.importorskip("lsst.sphgeom") |
| 131 | + |
| 132 | + reader = written_skymap_data["reader"] |
| 133 | + |
| 134 | + tract_ids = range(len(lsst_skymap)) |
| 135 | + for tract_id in tqdm(tract_ids, desc="Verifying written tracts", leave=False): |
| 136 | + # Verify tract geometry |
| 137 | + truth_quad = get_quad_from_tract_id(lsst_skymap, tract_id, inner=True) |
| 138 | + written_quad = reader.get_tract_vertices(tract_id) |
| 139 | + |
| 140 | + assert quads_are_equiv(truth_quad, written_quad), f"Tract {tract_id} geometry not preserved" |
| 141 | + |
| 142 | + # Verify all patch geometries |
| 143 | + for patch_id in range(100): |
| 144 | + truth_patch = get_quad_from_patch_id(lsst_skymap, tract_id, patch_id) |
| 145 | + written_patch = reader.get_patch_vertices(tract_id, patch_id) |
| 146 | + |
| 147 | + assert quads_are_equiv( |
| 148 | + truth_patch, written_patch |
| 149 | + ), f"Patch {patch_id} in tract {tract_id} geometry not preserved" |
0 commit comments