def test_observation_tod_array(): obs = lbs.Observation(detectors=3, n_samples_global=10, start_time_global=0.0, sampling_rate_hz=1.0) assert obs.tod.shape == (3, 10) assert obs.tod.dtype == np.float32
def test_observation_time(): ref_time = astrotime.Time("2020-02-20", format="iso") obs_no_mjd = lbs.Observation(detectors=1, start_time_global=0.0, sampling_rate_hz=5.0, n_samples_global=5) obs_mjd_astropy = lbs.Observation( detectors=1, start_time_global=ref_time, sampling_rate_hz=5.0, n_samples_global=5, ) assert isinstance(obs_no_mjd.get_delta_time(), float) assert np.allclose(obs_no_mjd.get_delta_time(), 0.2) assert isinstance(obs_no_mjd.get_time_span(), float) assert np.allclose(obs_no_mjd.get_time_span(), 1.0) assert isinstance(obs_mjd_astropy.get_delta_time(), astrotime.TimeDelta) assert np.allclose(obs_mjd_astropy.get_delta_time().to("ms").value, 200.0) assert isinstance(obs_mjd_astropy.get_time_span(), astrotime.TimeDelta) assert np.allclose(obs_mjd_astropy.get_time_span().to("ms").value, 1000.0) plain_times = obs_no_mjd.get_times() assert np.allclose(plain_times, np.array([0.0, 0.2, 0.4, 0.6, 0.8])) assert isinstance(obs_mjd_astropy.get_times(astropy_times=True), astrotime.Time) assert np.allclose( (obs_mjd_astropy.get_times(astropy_times=True) - ref_time).jd, np.array([ 0.0, 2.31481681e-06, 4.62962635e-06, 6.94444316e-06, 9.25925997e-06 ]), ) assert np.allclose( obs_mjd_astropy.get_times(normalize=False, astropy_times=False), np.array([ 6.98544069e8, 6.98544069e8, 6.98544070e8, 6.98544070e8, 6.98544070e8 ]), ) assert np.allclose(obs_mjd_astropy.get_times(normalize=True), np.array([0.0, 0.2, 0.4, 0.6, 0.8]))
def test_observation(): ref_time = astrotime.Time("2020-02-20", format="iso") obs_no_mjd = lbs.Observation( detector="A", start_time=0.0, sampfreq_hz=5.0, nsamples=5, use_mjd=False, ) obs_mjd = lbs.Observation( detector="B", start_time=float(ref_time.mjd), sampfreq_hz=5.0, nsamples=5, use_mjd=True, ) obs_mjd_astropy = lbs.Observation( detector="B", start_time=ref_time, sampfreq_hz=5.0, nsamples=5, use_mjd=True, ) assert np.allclose(obs_no_mjd.get_times(), np.array([0.0, 0.2, 0.4, 0.6, 0.8])) assert np.allclose( obs_mjd.get_times() - ref_time.mjd, np.array([ 0.0, 2.31481681e-06, 4.62962635e-06, 6.94444316e-06, 9.25925997e-06 ]), ) assert np.allclose( obs_mjd_astropy.get_times() - ref_time.mjd, np.array([ 0.0, 2.31481681e-06, 4.62962635e-06, 6.94444316e-06, 9.25925997e-06 ]), )
def test_write_simple_observation(tmp_path): obs = lbs.Observation(detectors=3, n_samples_global=10, start_time_global=0.0, sampling_rate_hz=1.0) files = lbs.write_list_of_observations(obs=obs, path=tmp_path) assert len(files) == 1 assert files[0].exists() # Try to open the file to check that it's a real HDF5 file with h5py.File(files[0], "r"): pass
def test_observation_tod_single_block(): comm_world = lbs.MPI_COMM_WORLD obs = lbs.Observation( detectors=3, n_samples_global=9, start_time_global=0.0, sampling_rate_hz=1.0, comm=comm_world, ) if comm_world.rank == 0: assert obs.tod.shape == (3, 9) assert obs.tod.dtype == np.float32 else: assert obs.tod.shape == (0, 0)
def test_make_bin_map_basic_mpi(): if lbs.MPI_COMM_WORLD.size > 2: return # Parameters res_map = np.arange(9).reshape(3, 3) + 1 n_samples = 10 psi = np.array([1, 2, 1, 4, 4, 1, 4, 0, 0, 0]) * np.pi / 5 pix = np.array([0, 0, 1, 0, 1, 2, 2, 0, 2, 1]) # Explicitely compute the dense pointing matrix and hence the TOD pointing_matrix = np.zeros((n_samples, ) + res_map.shape, dtype=np.float32) for i in range(len(res_map)): mask = pix == i pointing_matrix[mask, i, 0] = 1 pointing_matrix[mask, i, 1] = np.cos(2 * psi[mask]) pointing_matrix[mask, i, 2] = np.sin(2 * psi[mask]) tod = pointing_matrix.reshape(n_samples, -1).dot(res_map.reshape(-1)) # Craft the observation with the attributes needed for map-making obs = lbs.Observation( detectors=2, n_samples_global=5, start_time_global=0.0, sampling_rate_hz=1.0, comm=lbs.MPI_COMM_WORLD, ) if obs.comm.rank == 0: obs.tod[:] = tod.reshape(2, 5) obs.pixind = pix.reshape(2, 5) obs.psi = psi.reshape(2, 5) obs.set_n_blocks(n_blocks_time=obs.comm.size, n_blocks_det=1) res = mapping.make_bin_map([obs], 1)[:len(res_map)] assert np.allclose(res, res_map) obs.set_n_blocks(n_blocks_time=1, n_blocks_det=obs.comm.size) res = mapping.make_bin_map([obs], 1)[:len(res_map)] assert np.allclose(res, res_map)
def test_observation_tod_two_block_det(): comm_world = lbs.MPI_COMM_WORLD try: obs = lbs.Observation( detectors=3, n_samples_global=9, start_time_global=0.0, sampling_rate_hz=1.0, n_blocks_det=2, comm=comm_world, ) except ValueError: # Not enough processes to split the TOD, constuctor expected to rise if comm_world.size < 2: return if comm_world.rank == 0: assert obs.tod.shape == (2, 9) elif comm_world.rank == 1: assert obs.tod.shape == (1, 9) else: assert obs.tod.shape == (0, 0)
def test_observation_time(): comm_world = lbs.MPI_COMM_WORLD ref_time = astrotime.Time("2020-02-20", format="iso") obs_no_mjd = lbs.Observation( detectors=1, start_time_global=0.0, sampling_rate_hz=5.0, n_samples_global=5, comm=comm_world, ) obs_mjd_astropy = lbs.Observation( detectors=1, start_time_global=ref_time, sampling_rate_hz=5.0, n_samples_global=5, comm=comm_world, ) res_times = np.array([0.0, 0.2, 0.4, 0.6, 0.8]) res_mjd = np.array([ 0.0, 2.314_816_81e-06, 4.629_626_35e-06, 6.944_443_16e-06, 9.259_259_97e-06 ]) res_cxcsec = np.array([ 6.985_440_69e8, 6.985_440_69e8, 6.985_440_70e8, 6.985_440_70e8, 6.985_440_70e8 ]) if not comm_world or comm_world.rank == 0: assert np.allclose(obs_no_mjd.get_times(), res_times) assert np.allclose( (obs_mjd_astropy.get_times(astropy_times=True) - ref_time).jd, res_mjd) assert np.allclose( obs_mjd_astropy.get_times(normalize=False, astropy_times=False), res_cxcsec) else: assert obs_no_mjd.get_times().size == 0 assert obs_mjd_astropy.get_times(astropy_times=True).size == 0 assert obs_mjd_astropy.get_times(normalize=False, astropy_times=False).size == 0 if not comm_world or comm_world.size == 1: return obs_no_mjd.set_n_blocks(n_blocks_time=2) obs_mjd_astropy.set_n_blocks(n_blocks_time=2) if comm_world.rank == 0: assert np.allclose(obs_no_mjd.get_times(), res_times[:3]) assert np.allclose( (obs_mjd_astropy.get_times(astropy_times=True) - ref_time).jd, res_mjd[:3]) assert np.allclose( obs_mjd_astropy.get_times(normalize=False, astropy_times=False), res_cxcsec[:3], ) elif comm_world.rank == 1: assert np.allclose(obs_no_mjd.get_times(), res_times[3:]) assert np.allclose( (obs_mjd_astropy.get_times(astropy_times=True) - ref_time).jd, res_mjd[3:]) assert np.allclose( obs_mjd_astropy.get_times(normalize=False, astropy_times=False), res_cxcsec[3:], ) else: assert obs_no_mjd.get_times().size == 0 assert obs_mjd_astropy.get_times().size == 0
def test_construction_from_detectors(): comm_world = lbs.MPI_COMM_WORLD if comm_world.rank == 0: print(f"MPI configuration: {lbs.MPI_CONFIGURATION}") det1 = dict( name="pol01", wafer="mywafer", pixel=1, pixtype="A", channel=30, sampling_rate_hz=5, fwhm_arcmin=30, ellipticity=1.0, net_ukrts=1.0, fknee_mhz=10, fmin_hz=1e-6, alpha=1.0, pol="Q", orient="A", quat=[0.0, 0.0, 0.0, 0.0], ) det2 = dict( name="pol02", wafer="mywafer", pixel=2, # pixtype="B", channel=44, sampling_rate_hz=50, fwhm_arcmin=30, ellipticity=2.0, net_ukrts=1.0, fknee_mhz=10, fmin_hz=1e-6, # alpha=1.0, pol="Q", orient="A", quat=[1.0, 1.0, 1.0, 1.0], ) obs = lbs.Observation( detectors=[det1, det2], n_samples_global=100, start_time_global=0.0, sampling_rate_hz=1.0, comm=comm_world, root=0, ) if comm_world.rank == 0: assert obs.name[0] == "pol01" assert obs.name[1] == "pol02" assert obs.wafer[0] == "mywafer" assert obs.wafer[1] == "mywafer" assert obs.pixel[0] == 1 assert obs.pixel[1] == 2 assert obs.pixtype[0] == "A" assert obs.pixtype[1] is None assert obs.alpha[0] == 1.0 assert np.isnan(obs.alpha[1]) assert obs.ellipticity[0] == 1.0 assert obs.ellipticity[1] == 2.0 assert np.all(obs.quat[0] == np.zeros(4)) assert np.all(obs.quat[1] == np.ones(4)) if comm_world.size == 1: return obs.set_n_blocks(n_blocks_time=1, n_blocks_det=2) if comm_world.rank == 0: assert obs.name[0] == "pol01" assert obs.wafer[0] == "mywafer" assert obs.pixel[0] == 1 assert obs.pixtype[0] == "A" assert obs.ellipticity[0] == 1.0 assert np.all(obs.quat[0] == np.zeros(4)) assert obs.alpha[0] == 1.0 elif comm_world.rank == 1: assert obs.name[0] == "pol02" assert obs.wafer[0] == "mywafer" assert obs.pixel[0] == 2 assert obs.pixtype[0] is None assert obs.ellipticity[0] == 2.0 assert np.all(obs.quat[0] == np.ones(4)) assert np.isnan(obs.alpha[0]) else: assert obs.name is None assert obs.wafer is None assert obs.pixel is None assert obs.pixtype is None assert obs.ellipticity is None assert obs.quat is None assert obs.alpha is None obs.set_n_blocks(n_blocks_time=1, n_blocks_det=1) if comm_world.rank == 0: assert obs.name[0] == "pol01" assert obs.name[1] == "pol02" assert obs.wafer[0] == "mywafer" assert obs.wafer[1] == "mywafer" assert obs.pixel[0] == 1 assert obs.pixel[1] == 2 assert obs.pixtype[0] == "A" assert obs.pixtype[1] is None assert obs.ellipticity[0] == 1.0 assert obs.ellipticity[1] == 2.0 assert obs.alpha[0] == 1.0 assert np.isnan(obs.alpha[1]) assert np.allclose(obs.quat, np.arange(2)[:, None])
def test_observation_tod_set_blocks(): comm_world = lbs.MPI_COMM_WORLD try: obs = lbs.Observation( detectors=3, n_samples_global=9, start_time_global=0.0, sampling_rate_hz=1.0, n_blocks_time=2, comm=comm_world, ) except ValueError: # Not enough processes to split the TOD, constuctor expected to rise if comm_world.size < 2: return def assert_det_info(): if comm_world.rank < obs._n_blocks_time * obs._n_blocks_det: assert np.all(obs.row_int == (obs.tod[:, 0] // obs._n_samples_global).astype(int)) assert np.all(obs.row_int.astype(str) == obs.row_str) else: assert obs.row_int is None assert obs.row_str is None # Two time blocks ref_tod = np.arange(27, dtype=np.float32).reshape(3, 9) if comm_world.rank == 0: obs.tod[:] = ref_tod[:, :5] elif comm_world.rank == 1: obs.tod[:] = ref_tod[:, 5:] # Add detector info obs.setattr_det_global("row_int", np.arange(3)) obs.setattr_det_global("row_str", np.array("0 1 2".split())) assert_det_info() # Two detector blocks obs.set_n_blocks(n_blocks_time=1, n_blocks_det=2) if comm_world.rank == 0: assert np.all(obs.tod == ref_tod[:2]) elif comm_world.rank == 1: assert np.all(obs.tod == ref_tod[2:]) else: assert obs.tod.size == 0 assert_det_info() # One block obs.set_n_blocks(n_blocks_det=1, n_blocks_time=1) if comm_world.rank == 0: assert np.all(obs.tod == ref_tod) else: assert obs.tod.size == 0 assert_det_info() # Three time blocks if comm_world.size < 3: return obs.set_n_blocks(n_blocks_det=1, n_blocks_time=3) if comm_world.rank == 0: assert np.all(obs.tod == ref_tod[:, :3]) elif comm_world.rank == 1: assert np.all(obs.tod == ref_tod[:, 3:6]) elif comm_world.rank == 2: assert np.all(obs.tod == ref_tod[:, 6:]) else: assert obs.tod.size == 0 assert_det_info() # Two detector blocks and two time blocks if comm_world.size < 4: return obs.set_n_blocks(n_blocks_time=2, n_blocks_det=2) if comm_world.rank == 0: assert np.all(obs.tod == ref_tod[:2, :5]) elif comm_world.rank == 1: assert np.all(obs.tod == ref_tod[:2, 5:]) elif comm_world.rank == 2: assert np.all(obs.tod == ref_tod[2:, :5]) elif comm_world.rank == 3: assert np.all(obs.tod == ref_tod[2:, 5:]) else: assert obs.tod.size == 0 assert_det_info() try: obs.set_n_blocks(n_blocks_det=4, n_blocks_time=1) except ValueError: pass else: raise Exception("ValueError expected") # Two detector blocks and three time blocks if comm_world.size < 6: return obs.set_n_blocks(n_blocks_det=2, n_blocks_time=3) if comm_world.rank == 0: assert np.all(obs.tod == ref_tod[:2, :3]) elif comm_world.rank == 1: assert np.all(obs.tod == ref_tod[:2, 3:6]) elif comm_world.rank == 2: assert np.all(obs.tod == ref_tod[:2, 6:]) elif comm_world.rank == 3: assert np.all(obs.tod == ref_tod[2:, :3]) elif comm_world.rank == 4: assert np.all(obs.tod == ref_tod[2:, 3:6]) elif comm_world.rank == 5: assert np.all(obs.tod == ref_tod[2:, 6:]) else: assert obs.tod.size == 0 assert_det_info() # Three detector blocks and three time blocks if comm_world.size < 9: return obs.set_n_blocks(n_blocks_det=3, n_blocks_time=3) if comm_world.rank == 0: assert np.all(obs.tod == ref_tod[:1, :3]) elif comm_world.rank == 1: assert np.all(obs.tod == ref_tod[:1, 3:6]) elif comm_world.rank == 2: assert np.all(obs.tod == ref_tod[:1, 6:]) elif comm_world.rank == 3: assert np.all(obs.tod == ref_tod[1:2, :3]) elif comm_world.rank == 4: assert np.all(obs.tod == ref_tod[1:2, 3:6]) elif comm_world.rank == 5: assert np.all(obs.tod == ref_tod[1:2, 6:]) elif comm_world.rank == 6: assert np.all(obs.tod == ref_tod[2:, :3]) elif comm_world.rank == 7: assert np.all(obs.tod == ref_tod[2:, 3:6]) elif comm_world.rank == 8: assert np.all(obs.tod == ref_tod[2:, 6:]) else: assert obs.tod.size == 0 assert_det_info()