Task 1 — Can pixell replace CMBpipeline's projection + flat-sky Fourier step?

SO configuration, signal only, binary mask. Plan: docs/02_test_plan.md (revision 4). Analysis: notebooks/01_pixell_validation.ipynb. CMBpipeline commit 68ce262 (read-only); pixell 0.32.7, ducc0 0.38.0, healpy 1.18.1. 50 realizations, seeds 1000–1049.

+9 to +58 %
extra E→B leakage of A over curved-sky B, 24 ≤ ℓ < 1113 (9–82 σ)
48.5 vs 6.9
mode-mixing width at ℓ₀ = 800: A vs B (B = footprint only)
±11 % vs ±3.5 %
EE / input realization, 24 ≤ ℓ < 773: A vs B
9.0 s vs 0.45 s
a_ℓm → E/B maps per realization: A (as in CMBpipeline) vs B
Short answer. Yes, for the harmonic-space parts: working on the sphere with pixell (pipeline B) removes the projection, the interpolation, the ψ frame rotation and the flat-sky ℓ assignment. In our tests it gives measurably less E→B leakage, no projection-induced mode mixing, and EE within a few per cent of the input where A deviates by up to ±11 %. What it does not remove is the cut-sky E/B mixing of the binary SO mask, which dominates every pipeline at ℓ < 50 and near the mask edge. The intermediate pipeline C (CAR image + flat FFT) shows that more than half of A's extra leakage (55–75 % below ℓ ≈ 450, nearly all of it above) comes from the flat FFT itself, not from the projection.

1. What the original pipeline does in the projection/Fourier step

Documented in detail, with line references, in docs/01_current_pipeline.md. In short (SO case):

stepCMBpipeline functionwhat it does
skyutilities.make_maps → hp.synfast(pol=True)Q, U on HEALPix nside 512, lmax 1535, no pixel window, COSMO convention
regionsph_mask.make_SO_maskbinary mask: hits > 0.25 within 100° of the maximum-hits pixel; f_sky = 0.111; no apodization
framerotate_geo.psi_Q_to_P, make_rotrotates Q/U of every pixel to the frame of the patch centre, ψ ∈ [−76°, 78°]
projectionproj_2d.proj_conventionsazimuthal equidistant, x = θ sin φ (west), y = θ cos φ (north); pixels up to 56° from the centre
gridproj_2d.grid_bins_mask_from_res_margingriddata(method='cubic') (Clough–Tocher) onto 704 × 416 at 9.6′, 0 outside mask2d
Fourierutilities.transf_eb2_np, PowerSpectrum.powerFFT with tfac = √(dx dy / nx ny), ℓ = |k|, dx = 9.553′, dy = 9.315′ (≠ 9.6′ grid pitch)
E/Btransf_eb2_npE = cos2φ Q + sin2φ U, B = −sin2φ Q + cos2φ U with 2φ = 2 atan2(ℓ_y, −ℓ_x); periodic boundaries

2. Which pixell functions replace each operation

operationCMBpipeline (A)pixell, sphere (B)why the pixell operation is appropriate
pixelizationHEALPix → equidistant plane 704 × 416enmap.fullsky_geometry(res=9.6′, variant='fejer1'), 2250 × 11259.6′ divides the sphere (1125 rings); fejer1 has exact ducc quadrature (quad_weights)
a_ℓm → Q/Uhp.alm2map then interpolationcurvedsky.alm2map(spin=[0,2])exact spin-2 synthesis at the pixel centres; same local (θ, φ) basis and sign as healpy (checked to 10⁻¹²)
frame rotationψ per pixelnoneCAR pixels are addressed in (Dec, RA): Q/U are defined w.r.t. local north everywhere, as on the sphere
projection + interpolationequidistant + Clough–Tochernonemaps are samples of the band-limited field, no resampling
maskdefine_region_mask_from_res_marginsHEALPix mask read at each CAR pixel centrethe same nearest-pixel rule as CMBpipeline, same physical region (4583 deg²)
Q/U → E/Bflat FFT, transf_eb2_npcurvedsky.map2alm(spin=2, lmax=1124)spherical spin-2 analysis with exact quadrature up to ℓ = 1124 (round trip 2×10⁻¹²)
E/B mapsirfft2 / tfaccurvedsky.alm2map(spin=0)E, B are scalar fields
power spectrumPowerSpectrum.power, ℓ = |k|, / w₂curvedsky.alm2cl of the a_E, a_B of the masked Q/U, / w₂multipoles are true ℓ; w₂ = area-weighted ⟨mask²⟩; no re-masking, no MASTER
cut-out region—B on the 1110 × 324 region of the mask: alm2map, map2alm(..., method='2d'), alm2mappixell pads to the full sphere with exact weights: identical to full-sky B (10⁻¹³); default 'cyl' is approximate (4×10⁻⁴)

Intermediate pipeline C uses curvedsky.rotate_alm (patch centre → (0, 0), exact Wigner-D rotation), alm2map on a 708 × 397 CAR patch, and enmap.map2harm(normalize='phys', spin=[2]), whose queb_rotmat uses the HEALPix convention with the signed pixel step of laxes. It keeps the flat FFT of A but samples the field exactly in a grid-aligned frame, so A − C isolates projection + interpolation + ψ, and C − B isolates the flat-sky Fourier treatment.

3. The mathematical difference between the approaches

Flat sky (A, C). The map is treated as a function on a periodic rectangle; with Fourier modes ℓ = (ℓ_x, ℓ_y) and φ_ℓ the angle of ℓ,

E(ℓ) ± i B(ℓ) = e∓2iφ_ℓ [Q(ℓ) ± i U(ℓ)],   multipole assigned as ℓ = |ℓ|

This is exact only for a field on a flat, periodic plane. On the SO patch three things break it: (i) the map from the sphere to the plane is not an isometry (equidistant: tangential stretch θ/sin θ up to 1.18; CAR: horizontal scale cos Dec), so a spherical multipole spreads over a range of |ℓ| and its centre shifts; (ii) Q/U must first be expressed in one global frame (A's ψ rotation), which is only approximate for a non-conformal map; (iii) the FFT assumes periodicity across the zero-filled edges.

Curved sky (B). Q ± iU are expanded in spin-weighted harmonics on the sphere,

(Q ± iU)(n̂) = Σℓm ±2aℓm ±2Yℓm(n̂),   aEℓm = −(2aℓm + −2aℓm)/2,  aBℓm = i(2aℓm − −2aℓm)/2

which is defined in the local basis at every point, needs no global frame and assigns the true multipole ℓ. map2alm evaluates these integrals with exact quadrature on the CAR rings. With a mask, the result is the harmonic transform of (mask × field): the only remaining effect is the coupling due to the footprint itself (a narrow kernel, ~7 in ℓ for this mask) and the cut-sky E/B mixing (ambiguous modes near the edge), common to any method that does not purify.

4. Exact test configuration

parametervalue
inputone set of a_ℓm^{T,E,B} from utilities.signal_spectrum(r=0.034) (CAMB lensed + tensor), TE = TB = EB = 0, curvedsky.rand_alm(seed)
band limitlmax = 1535 (3 nside − 1)
beamGaussian FWHM 23′ (σ = 9.77′), applied once to a_E, a_B with almxfl; no pixel window
noisenone (signal only)
maskSO binary mask on HEALPix nside 512 (349,440 pixels, 4582.5 deg², f_sky 0.1111), transferred by nearest HEALPix pixel; no apodization
A704 × 416 plane, 9.6′ pitch, margin 76.8′; FFT dx = 9.553′, dy = 9.315′; 189,097 pixels in mask2d
BCAR fejer1 9.6′, 2250 × 1125 (full sky; patch in a 1110 × 324 box); map2alm lmax 1124; 286,159 pixels in the mask
Crotated CAR patch 9.6′, 708 × 397, same margin; 186,278 pixels in the mask
controlsA′: FFT with dx = dy = 9.6′; B 6′: CAR fejer1 6′, 3600 × 1800, map2alm lmax 1535
binningcompute_bins_fractional(4, 1000, 0.2, 20) = 4, 24, 44, 64, 84, 104, 125, 150, 180, 216, 259, 311, 373, 447, 537, 644, 773, 927, 1113; low ℓ: Δℓ = 10 from 2 to 102
referencesfull-sky: alm2cl of the input; cut-sky (per pipeline): true E/B × its own 2D mask through its own transform
realizationsmap level: seed 1000; spectra: 50 seeds (1000–1049), full and E-only inputs; mode mixing: 7 shells ℓ₀ ± 2, 10 realizations each
The same physical SO region on the three geometries: A's plane, B's full-sky CAR (cut-out for display), C's rotated CAR patch.
The same physical SO region on the three geometries: A's plane, B's full-sky CAR (cut-out for display), C's rotated CAR patch.

5. Plots and quantitative results

5.1 Validation of the ingredients

checkresult
cached triangulation vs CMBpipeline griddatabit-identical
pixell alm2map vs healpy Q/Umax difference 1.0×10⁻¹² of the RMS (same polarization convention)
9.6′ fejer1 map2alm round trip, ℓ ≤ 11242.2×10⁻¹² (fails at ℓ = 1200: 0.96)
rotate_alm(−λ_c, δ_c, 0)T′(R n) = T(n) to 2.6×10⁻¹²
correlation of E with E_true (seed 1000)A −0.9961 (sign flip predicted in Phase 1), B +0.9964, C +0.9961
RMS(E − E_true)/RMS(E_true) in the maskA 0.0918, B 0.0860, C 0.0931
Pipeline A (seed 1000): interpolated Q, U and the flat-FFT E, B images on the 704 × 416 plane (A's E/B have the opposite sign to healpy/pixell).
Pipeline A (seed 1000): interpolated Q, U and the flat-FFT E, B images on the 704 × 416 plane (A's E/B have the opposite sign to healpy/pixell).
Pipeline B: Q, U on the CAR sphere and the E, B maps from the masked spin-2 map2alm (display cut-out).
Pipeline B: Q, U on the CAR sphere and the E, B maps from the masked spin-2 map2alm (display cut-out).
Pipeline C: Q, U on the rotated CAR patch and the flat-FFT E, B.
Pipeline C: Q, U on the rotated CAR patch and the flat-FFT E, B.

5.2 E/B leakage (E-only input)

B maps recovered from an E-only sky, seed 1000. Colour range = 3 × RMS of the true B of the full input.
B maps recovered from an E-only sky, seed 1000. Colour range = 3 × RMS of the true B of the full input.
distance to mask edge0–1°1–2°2–4°4–8°> 8°
A0.2910.1150.0960.0800.052
B0.2630.0840.0650.0530.035
C0.2770.1010.0820.0670.056

RMS of the leaked B map / RMS of the true E map, seed 1000. The leakage sits at the edge in all pipelines; away from it B leaks ~30 % less than A.

ℓ binB: leaked BB / theory BBA − BσC − Bσ
4–2423.76-15.414-9.1-15.818-9.1
24–442.63+0.2249.4+0.1406.2
44–642.30+0.29011.6+0.1938.8
64–842.34+0.37516.4+0.21513.1
84–1042.28+0.42715.6+0.30318.1
104–1252.22+0.42620.6+0.26417.0
125–1501.90+0.37327.6+0.25119.9
150–1801.45+0.24431.0+0.15920.8
180–2161.08+0.20027.9+0.13727.2
216–2591.04+0.34445.1+0.18630.4
259–3111.29+0.67182.1+0.38546.5
311–3731.72+0.99875.5+0.58882.7
373–4471.96+0.80578.5+0.62187.4
447–5371.93+0.33354.9+0.34251.7
537–6442.68+0.54961.4+0.45355.3
644–7735.67+1.26366.1+1.28170.1
773–92719.64+5.82065.2+5.54573.0
927–1113177.34+93.31865.1+84.46888.8

Mean over 50 realizations, paired differences in units of their standard error. From ℓ = 24 on, A leaks systematically more than B (9–82 σ), by 9–33 % of B's leakage below ℓ ≈ 260, 41–58 % at 260–450 and 17–53 % above; C's excess is 55–75 % of A's below ℓ ≈ 450 and about equal to it above. The first bin (4–24) goes the other way; see §7.

5.3 Power-spectrum recovery

N = 50: EE and BB relative to each pipeline's cut-sky reference (top), EE relative to the input realization and the leaked BB of the E-only sky (bottom).
N = 50: EE and BB relative to each pipeline's cut-sky reference (top), EE relative to the input realization and the leaked BB of the E-only sky (bottom).
ℓ binAA′BCB 6′
4–240.3440.3480.7460.3290.747
24–441.0441.1120.9841.0000.984
44–640.9951.0530.9650.9410.965
64–841.0061.0570.9780.9510.978
84–1040.9911.0260.9770.9540.977
104–1250.9650.9770.9670.9470.967
125–1500.9700.9670.9800.9760.980
150–1800.9590.9200.9900.9940.990
180–2161.0191.0281.0111.0291.011
216–2591.1141.2511.0060.9721.006
259–3111.0361.1250.9830.9390.983
311–3730.9830.9980.9840.9570.984
373–4470.9330.8700.9921.0040.992
447–5370.9370.8201.0121.1071.012
537–6441.0081.0311.0120.9831.012
644–7730.8980.7741.0111.0601.011
773–9271.0850.9111.1601.4171.149
927–11131.5421.3691.5261.8541.440

EE / input realization (full-sky reference), mean of 50. This ratio contains both the mask and the pipeline: B stays within 0.965–1.012 for 24 ≤ ℓ < 773; A oscillates between 0.898 and 1.114 (power displaced in ℓ by the projection); A′ (true 9.6′ pitch) is worse (0.774–1.251); C deviates up to +10.7 % (cos Dec scale of the CAR patch). All pipelines lose power in the first bin and gain it above ℓ ≈ 800, where the beam has reduced the signal to ~10⁻³ and mask-edge power dominates.

ℓ binB: EE / cut-sky refA − BσC − Bσ
4–240.778-0.087-3.5-0.085-3.2
24–440.917-0.006-2.0-0.002-0.6
44–640.963-0.002-1.9-0.003-2.5
64–840.976-0.003-4.5-0.001-1.3
84–1040.982-0.003-3.7-0.003-4.7
104–1250.986-0.004-6.0-0.003-4.4
125–1500.987-0.003-6.7-0.002-4.4
150–1800.986-0.004-8.3-0.002-5.9
180–2160.981-0.004-7.3-0.002-4.4
216–2590.987-0.003-7.2-0.003-7.8
259–3110.994-0.004-20.9-0.002-11.4
311–3730.996-0.003-31.7-0.002-14.2
373–4470.996-0.004-43.8-0.001-12.4
447–5370.990-0.006-35.1-0.001-5.1
537–6440.988-0.012-75.0-0.002-14.2
644–7730.987-0.021-93.0-0.002-11.0
773–9270.914-0.052-69.5-0.003-4.1
927–11130.774-0.087-43.7-0.035-27.3

Relative to each pipeline's own cut-sky reference (which cancels the mask coupling), A loses systematically more EE to B than B does, 0.3 % at ℓ ≈ 100–450 growing to 2 % at 644–773 and 5–9 % above. Note that for the flat pipelines this reference also contains the projection's own mode mixing (see 5.4), so this table measures only the E/B-separation part.

Single realization (seed 1000): EE and BB relative to the full-sky reference (top, dotted = cut-sky reference) and to the cut-sky reference (bottom).
Single realization (seed 1000): EE and BB relative to the full-sky reference (top, dotted = cut-sky reference) and to the cut-sky reference (bottom).

5.4 Mode mixing

E-only shells ℓ₀ ± 2 (10 realizations each): recovered EE vs output ℓ (Δℓ = 4), normalized.
E-only shells ℓ₀ ± 2 (10 realizations each): recovered EE vs output ℓ (Δℓ = 4), normalized.
ℓ₀width ABCA refB refC refA no maskC no maskshift ABC
307.97.17.18.47.77.97.56.9+0.2+0.7+0.8
607.46.88.27.66.98.58.07.5-0.1+0.5+1.2
1009.16.79.29.46.89.410.09.3-0.6+0.5+1.6
20014.86.812.715.16.912.916.714.8-1.9+0.5+2.3
40024.96.821.925.36.922.231.527.3-3.7+0.3+4.0
60036.56.931.636.86.931.946.938.9-6.3+0.1+5.8
80048.56.939.648.66.939.962.549.8-9.0-0.1+7.5

Width = 84th − 16th percentile of the response (the paper's Table 5 definition); shift = ⟨ℓ⟩ − ℓ₀. B's width is constant (~6.9): it is the SO footprint kernel (the unmasked B returns the shell exactly, width ~5 = the shell itself). A's width grows linearly with ℓ₀ (48.5 at 800) and its centroid moves to lower ℓ (−9.0 at 800), consistent with the paper's App. B (23.8 at ℓ₀ = 800 for a smaller patch without mask). A's cut-sky reference has the same width, so the broadening comes from placing the exact field on the plane and FFT-ing it, not from the E/B separation. Without mask A is even wider (62.5), because the whole rectangle reaches larger distances from the centre. C broadens too (39.6) and shifts to higher ℓ (+7.5), from the cos Dec scale of the CAR patch.

5.5 Computational time

pipelinestepstime per realization
A as in CMBpipelinealm2map 0.47 s + rotate/project/griddata 8.47 s + flat E/B 0.02 s8.97 s
A, cached triangulationsame interpolant, triangulation built once3.27 s
B (full sky)alm2map 0.24 s + map2alm 0.21 s0.45 s
B on the cut-out regionalm2map + map2alm (method 2d) + alm2map on 1110 × 3240.37 s
Crotate_alm + alm2map + map2harm1.12 s

One realization, 12 threads available (pixell/ducc and healpy are multi-threaded; scipy's interpolation is not).

6. Which flat-sky/projection approximations are removed, reduced, or still present

approximation (Phase 1)ACBevidence
sphere → plane map (equidistant, non-isometric)presentreplaced by CAR patch (cos Dec 0.79–1)removedmode-mixing width 48.5 / 39.6 / 6.9 at ℓ₀ = 800
Clough–Tocher interpolationpresentremovedremovedexact synthesis; A's Q/U residual 3 %, transfer 0.978 at ℓ = 1000 (preliminary Phase 3 run)
global Q/U frame (ψ rotation, non-conformal)present (1.4° RMS, 4.3° max off the projection frame; preliminary Phase 3 run)removedremovedCAR axes are local meridians
ℓ = |k| on the plane; dx/dy ≠ grid pitchpresentℓ = |k| with mean CAR stepremovedEE/input ±11 % (A), ±3.5 % (B)
periodic FFT on a zero-filled patchpresentpresentremovedC − B leakage excess 6–88 σ
flat beam exp(−k²σ²/2)present (loss/OQE only)—removednot exercised here (beam applied to a_ℓm)
cut-sky E/B mixing of the binary maskpresentpresentpresentleakage 26–29 % of RMS(E) within 1° of the edge in all three
finite band limit of the gridℓ_N ≈ 1125ℓ_N ≈ 1125reduced: exact to 1124; 6′ control exact to 17999.6′ vs 6′ identical to 0.1 % below ℓ ≈ 650

7. Discrepancies and unresolved issues

8. Follow-up: pixel sizes, controls, and a 2D image for the network

8.1 CAR pixel size

B's 2250 × 1125 map is the whole sphere. Each pixel is 9.6′ in Dec and 9.6′ of RA, i.e. 9.6′ × cos(Dec) of true arc in RA, because every ring has the same 2250 pixels while its circumference is 2π cos Dec (checked with enmap.pixshapemap):

Decheightwidtharea
0°9.60′9.60′92.2 arcmin²
−25° (patch north edge)9.60′8.70′83.5 arcmin²
−47.5° (patch centre)9.60′6.48′62.3 arcmin²
−73° (patch south edge)9.60′2.81′26.9 arcmin²

So along Dec B samples exactly like A (ℓ_N ≈ 1125) and along RA it is finer everywhere in the patch: never coarser than A. The unequal areas do not bias B, because map2alm uses the exact ring quadrature weights. They would bias a flat FFT, which is why C rotates the patch to the equator first (Dec −73…−25° → −38…+23°, cos Dec ratio 3.1 → 1.27).

8.2 Why the 6′ control

B at 9.6′ was chosen to match A, but at 9.6′ map2alm is exact only up to ℓ = 1124 while the input goes to 1535 (beamed variance above 1125: ~6×10⁻⁶), and the mask edge is a coarser staircase. The 6′ run (exact to 1799, finer edge) checks that these limits do not drive the A–B differences: the two agree to 0.1 % below ℓ ≈ 650 and differ by 3–8 % above ℓ ≈ 800 (e.g. EE / cut-sky reference 0.80 vs 0.77 in the last bin), where A is still worse (0.69). The pixel size is set by the beam and the band limit: 9.6′ is adequate below ℓ ≈ 650 and marginally limiting above ℓ ≈ 800.

8.3 Why C's mask looks like A's

C is also a map of the sphere onto a rectangle centred on the patch with north up (cylindrical, plate carrée after the rotation), and A is azimuthal equidistant. Both keep distances along the two central axes exactly, and within the patch they differ by at most ~5°:

sky point, C's (RA′, Dec′)same point on A's plane (x, y)
(0°, 30°)(0.0°, 30.0°)
(50°, 0°)(50.0°, 0.0°)
(30°, 20°)(28.7°, 20.9°)
(50°, 30°)(44.9°, 33.8°)
(−50°, −35°)(−43.0°, −39.3°)

That is why C inherits a similar flat-sky mode mixing (39.6 vs 48.5 at ℓ₀ = 800) while B, on the same kind of CAR pixels but never treated as a plane, does not (6.9). B is displayed in equatorial RA/Dec, where the patch (Dec −73° to −25°) looks different; for B the shape of the picture is only a display choice.

8.4 Pipeline B on the cut-out region: a smaller array, still curved sky

The full 2250 × 1125 map is ~89 % zeros. Notebook section 6b runs pipeline B on the region that contains the mask only: the rows and columns of the 9.6′ fejer1 grid around mask_B (1110 × 324 = 359,640 pixels, 14 % of the sphere, of which 286,159 observed). The steps are the same as in B, never treating the map as a plane:

  1. Q, U with curvedsky.alm2map(spin=2) directly on the cut-out geometry;
  2. multiply by the mask on the cut-out;
  3. curvedsky.map2alm(spin=2, method='2d') → a_E, a_B: the cut-out is a slice of the full-sky fejer1 grid, so pixell pads it with zeros back to the sphere and uses the exact ring quadrature;
  4. curvedsky.alm2map(spin=0) → E, B maps on the same 1110 × 324 cut-out.
comparison with the full-sky pipeline Bresult
Q/U on the cut-out vs full-sky Q/U on the same pixels1.2×10⁻¹³
a_E, a_B1.6×10⁻¹⁴
E/B maps on the cut-out vs full-sky E/B on the same pixels1.7×10⁻¹³
C_ℓ^EE, C_ℓ^BB, 2 ≤ ℓ ≤ 1124identical to 1×10⁻¹³
RMS(E − E_true)/RMS(E_true) in the mask0.0860 (full sky: 0.0860)
same, with the default method='cyl'a_ℓm off by 4.0×10⁻⁴ (approximate ring weights)
time (alm2map + map2alm + alm2map)0.37 s
Pipeline B on the cut-out
Pipeline B on the cut-out (1110 × 324): masked Q, U and the curved-sky E, B maps, and their difference with the full-sky pipeline B (~10⁻¹⁴).

So the curved-sky pipeline can run on an array of the size of the observed region, with results identical to the full sphere, as long as map2alm is called with method='2d'. Two remarks for using such an array as the 2D input of a network (not done in Task 1): the E/B fields of a masked sky extend slightly outside the mask and are truncated at the border of the cut-out (the a_ℓm and spectra are unaffected); and in equatorial CAR the pixels of this region are 9.6′ tall but 2.8′–8.7′ wide (§8.1), so the image is not isotropic. If that matters for the convolutions, the same procedure works on a patch rotated to the equator (pixels 7.6′–9.6′ wide; also exact with method='2d', 7×10⁻¹⁴), keeping every harmonic step on the sphere.