Skip to content

Conversation

@paganol
Copy link
Member

@paganol paganol commented Dec 13, 2025

This PR introduces a new data model and integrates ducc0 for high-accuracy operations. It includes several breaking changes.

1. New Module: maps_and_harmonics.py

We introduced a centralized module for map and harmonic operations, featuring two new data classes:

  • HealpixMap: A container for map data that carries unit and coordinate metadata.
  • SphericalHarmonics: Updated to include unit and coordinate fields alongside coefficients.

2. Robust scan_map Interface (Breaking Change)

We aligned scan_map and convolve_sky with the map-making interfaces.

  • Type Enforcement: You can no longer pass raw numpy arrays. Inputs must be HealpixMap or SphericalHarmonics objects.
  • Automatic Rotations: While this enforces strict typing, it significantly improves robustness. The code now automatically detects the input frame and applies the necessary pointing rotations, eliminating manual flag errors.

3. ducc0 Wrapper Functions

We added ducc0 wrappers to maps_and_harmonics.py for efficient transforms:

  • interpolate_alm: Synthesizes signal at arbitrary detector positions (via ducc0.sht.synthesis_general).
  • pixelize_alm: Converts $a_{\ell m} \to$ HEALPix map (via ducc0.sht.synthesis).
  • estimate_alm: Converts HEALPix map $\to a_{\ell m}$ (via ducc0.sht.adjoint_synthesis).

4. Improved interpolation in scan_map

The scan_map interpolation logic has been improved removing the explicit interpolation flag, now:

  • Pixel-space scan: If a HealpixMap is passed, the code performs direct pixel lookup (ang2pix).
  • Harmonic-space scan: If SphericalHarmonics are passed, the code automatically uses interpolate_alm. This replaces the linear interpolation with exact synthesis.

5. Updates to units.py (Breaking Change)

We refactored units.py to standardize naming conventions and expand functionality:

  • Renamed Constants: some physical constants in constants.py have been renamed. In the future we should make the naming convention more uniform.
  • New Utilities: Added functions to handle unit conversions more transparently within the simulation pipeline.

6. Mbs Output Updates

The Mbs class has been updated to fully utilize the new containers. It now outputs either HealpixMap or SphericalHarmonics objects, ensuring that all generated maps and alms automatically carry the correct unit and coordinate metadata.

7. Spectral Utilities (Prep for #425)

To support future work on Mbs, we added utility functions:

  • synthesize_alm: Generates $a_{\ell m}$ from input power spectra.
  • compute_cl: Computes angular power spectra ($C_\ell$) from $a_{\ell m}$ objects.

⏳ Remaining Tasks / Future Work

There are still a few things that need to be addressed:

  • Check the documentation: Ensure the new classes and API changes are reflected in the docs.
  • Update notebooks: Tutorials need to be updated to use the new object-oriented interface.
  • Refine hwp_harmonic: The interface for pointing and metadata in this module can be improved (though it currently passes tests). Here I can try to improve it and then @mj-gomes can check it.
  • Implement Unit Checks: While the containers now hold unit info, we do not yet strictly check that TOD units match the Map/Alm units in scan_map. This should be straightforward to add now.

Regarding the connection with PR #425
It might be strategic to unify the two activities. I propose merging PR #425 into this branch and continuing the development here. This would ensure that the Mbs rework is immediately aligned with the new data containers and ducc0 integration.
What do you think? @ziotom78 @ggalloni @mj-gomes

@paganol paganol linked an issue Dec 13, 2025 that may be closed by this pull request
@paganol paganol mentioned this pull request Dec 16, 2025
5 tasks
@paganol
Copy link
Member Author

paganol commented Dec 22, 2025

I added a new module, input_sky.py, which is a candidate for replacing mbs.py.

In detail, compared to mbs.py, this module introduces the following changes:

  • Noise generation removed: This was never really used and should not be here.
  • Simplified Foreground Interface: Removed the intermediate abstraction layer for foreground models. We now invoke PySM directly using its standard preset strings (e.g., 's1', 'd1').
    • (Note to @NicolettaK / @ziotom78: I am unsure why the intermediate layer existed in mbs; let me know if there was a specific reason to keep it).
  • Removed MC & MPI dependency: Removed the internal Monte Carlo generation loops and MPI interface. Consistency of CMB realizations across different MPI tasks is now ensured simply by using a common random seed.
  • Healpy dependency removed: Replaced all healpy calls with the ducc0 interface included in maps_and_harmonics.py.
  • I/O removed: Removed the internal saving of maps to disk.
  • Coordinate System: Removed the rotation to Ecliptic coordinates; the default is now always Galactic. Since the rest of litebird_sim handles coordinates transparently, this option is no longer needed.
  • Beam & Window Functions: Added more transparent handling of beam smoothing and pixel window functions.

Let me know what you think. I can easily add other features or change implementation details based on your feedback.

One design question:
Currently, input_sky._get_cmb_unit_conversion handles the conversion factor computation. I think this logic fits better within the BandPassInfo class as it might be useful for other modules. In general, we should consider going through BandPassInfo to improve the class (handling conversion factors, color corrections, etc.) and explore its interplay with the UnitUtils class further. Thoughts?

@github-actions
Copy link

github-actions bot commented Dec 23, 2025

Coverage report

Click to see where and how coverage changed

FileStatementsMissingCoverageCoverage
(new stmts)
Lines missing
  litebird_sim
  __init__.py
  beam_convolution.py 426
  beam_synthesis.py 296-328
  constants.py
  coordinates.py
  dipole.py 61, 75-78, 83-84
  grasp2alm.py 303-308
  healpix.py 52, 56, 257
  hwp_harmonics.py 549-557, 656-665, 694, 704-708, 732-734, 745-759, 801
  input_sky.py 67-122, 175-180, 203-225, 229-304, 308-374, 378-436, 443-480
  io.py
  madam.py
  maps_and_harmonics.py 98, 105, 113, 143, 190, 229, 232, 255, 281, 299-303, 343, 360, 368, 371, 376, 381, 388, 406-435, 438-466, 475-502, 531, 537, 561, 597, 606, 610, 617-641, 648, 676-683, 703-708, 729-731, 746, 749, 752, 755, 821-825, 923-924, 943, 950, 969, 1008-1010, 1155, 1160, 1173, 1202, 1205, 1210, 1215, 1224, 1228, 1235, 1238, 1243, 1248, 1255, 1273-1300, 1346, 1383, 1405, 1422, 1425, 1428, 1431, 1502-1554, 1639-1713, 1801-1869, 1990, 2090, 2122, 2125-2131, 2188, 2217-2247, 2311-2315, 2329-2333, 2341, 2347, 2439, 2462-2497, 2523-2576, 2619-2644
  mpi.py
  scan_map.py 225, 233, 240-241, 281-283, 292-306, 333-339, 482-488, 501-504, 510
  simulations.py 1678-1688
  units.py 43, 48, 53, 74-131, 139-147, 155-160
  litebird_sim/mapmaking
  binner.py
  brahmap_gls.py
  destriper.py
  litebird_sim/mbs
  mbs.py 1047
Project Total  

This report was generated by python-coverage-comment-action

For some reason commits were passed without the pre-commit filtering, so some errors passed through
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.

Add ducc0 interpolation option to scan_map

3 participants