@@ -418,3 +418,85 @@ def test_inverting_mixing_matrices():
418418 _mixed_cls = np .sum (mixed_cls [key ].array )
419419 print (key , _mixed_cls )
420420 np .testing .assert_allclose (_mixed_cls , (n + 1 ) * 1.0 )
421+
422+
423+ def test_nonsquare_mixing_matrix_metadata_binning_and_io (tmp_path ):
424+ import heracles
425+
426+ from heracles .twopoint import Result , apply_mixing_matrix , invert_mixing_matrix
427+
428+ key = ("POS" , "POS" , 0 , 0 )
429+
430+ in_ell = np .arange (8 )
431+ out_ell = np .array ([2.0 , 4.0 , 6.0 , 8.0 , 10.0 ])
432+ out_lower = np .array ([1.5 , 3.5 , 5.5 , 7.5 , 9.5 ])
433+ out_upper = np .array ([2.5 , 4.5 , 6.5 , 8.5 , 10.5 ])
434+
435+ cls_in = {
436+ key : Result (
437+ np .linspace (1.0 , 8.0 , in_ell .size ),
438+ spin = (0 , 0 ),
439+ axis = (0 ,),
440+ ell = in_ell ,
441+ )
442+ }
443+
444+ mm = {
445+ key : Result (
446+ np .arange (out_ell .size * in_ell .size , dtype = float ).reshape (
447+ out_ell .size , in_ell .size
448+ ),
449+ spin = (0 , 0 ),
450+ axis = (0 ,),
451+ ell = out_ell ,
452+ lower = out_lower ,
453+ upper = out_upper ,
454+ )
455+ }
456+
457+ mixed = apply_mixing_matrix (cls_in , mm )
458+ np .testing .assert_array_equal (mixed [key ].ell , out_ell )
459+ np .testing .assert_array_equal (mixed [key ].lower , out_lower )
460+ np .testing .assert_array_equal (mixed [key ].upper , out_upper )
461+
462+ bins = np .array ([2.0 , 5.0 , 11.0 ])
463+ mixed_binned = heracles .binned (mixed , bins )
464+ assert mixed_binned [key ].shape == (2 ,)
465+ np .testing .assert_array_equal (mixed_binned [key ].lower , bins [:- 1 ])
466+ np .testing .assert_array_equal (mixed_binned [key ].upper , bins [1 :])
467+
468+ mixed_path = tmp_path / "mixed_nonsquare.fits"
469+ heracles .write (mixed_path , mixed_binned )
470+ mixed_read = heracles .read (mixed_path )
471+ np .testing .assert_array_equal (mixed_read [key ], mixed_binned [key ])
472+ np .testing .assert_array_equal (mixed_read [key ].ell , mixed_binned [key ].ell )
473+
474+ inv_mm = invert_mixing_matrix (mm , rcond = 1e-12 )
475+ assert inv_mm [key ].shape == (in_ell .size , out_ell .size )
476+ np .testing .assert_array_equal (inv_mm [key ].ell , np .arange (in_ell .size ))
477+ np .testing .assert_array_equal (inv_mm [key ].lower , np .arange (in_ell .size ))
478+ np .testing .assert_array_equal (inv_mm [key ].upper , np .arange (1 , in_ell .size + 1 ))
479+
480+ cls_out = {
481+ key : Result (
482+ np .linspace (1.0 , out_ell .size , out_ell .size ),
483+ spin = (0 , 0 ),
484+ axis = (0 ,),
485+ ell = out_ell ,
486+ )
487+ }
488+
489+ unmixed = apply_mixing_matrix (cls_out , inv_mm )
490+ np .testing .assert_array_equal (unmixed [key ].ell , np .arange (in_ell .size ))
491+ np .testing .assert_array_equal (unmixed [key ].lower , np .arange (in_ell .size ))
492+ np .testing .assert_array_equal (unmixed [key ].upper , np .arange (1 , in_ell .size + 1 ))
493+
494+ inv_bins = np .array ([0.0 , 4.0 , 8.0 ])
495+ unmixed_binned = heracles .binned (unmixed , inv_bins )
496+ assert unmixed_binned [key ].shape == (2 ,)
497+
498+ unmixed_path = tmp_path / "unmixed_nonsquare.fits"
499+ heracles .write (unmixed_path , unmixed_binned )
500+ unmixed_read = heracles .read (unmixed_path )
501+ np .testing .assert_array_equal (unmixed_read [key ], unmixed_binned [key ])
502+ np .testing .assert_array_equal (unmixed_read [key ].ell , unmixed_binned [key ].ell )
0 commit comments