Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix a bug in the MWA beams where the polarization responses were swapped #1485

Merged
merged 4 commits into from
Oct 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ telescope object from the metadata.
antennas with data.

### Fixed
- A bug in the MWA beam reader that resulted in the wrong polarization response
(the azimuthal-aligned response was swapped with the zenith angle-aligned response).
- A bug in reading UVH5 files with antenna names saved as variable length strings
that was introduced in v3.0.0.

Expand Down
4 changes: 2 additions & 2 deletions src/pyuvdata/uvbeam/mwa_beam.py
Original file line number Diff line number Diff line change
Expand Up @@ -475,8 +475,8 @@ def _get_response(self, *, freqs_hz, pol_names, beam_modes, phi_arr, theta_arr):
Sigma_P = np.inner(phi_comp, emn_P_sum)
Sigma_T = np.inner(phi_comp, emn_T_sum)

jones[pol_i, 0, freq_i] = Sigma_T
jones[pol_i, 1, freq_i] = -Sigma_P
jones[pol_i, 0, freq_i] = -Sigma_P
jones[pol_i, 1, freq_i] = Sigma_T

return jones

Expand Down
50 changes: 50 additions & 0 deletions tests/uvbeam/test_mwa_beam.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,56 @@ def test_read_write_mwa(mwa_beam_1ppd, tmp_path):
assert beam1 == beam2


@pytest.mark.filterwarnings("ignore:There are some terminated dipoles")
def test_mwa_orientation(mwa_beam_1ppd):
power_beam = mwa_beam_1ppd.efield_to_power(inplace=False)

za_val = np.nonzero(np.isclose(power_beam.axis2_array, 15.0 * np.pi / 180))

east_az = np.nonzero(np.isclose(power_beam.axis1_array, 0))
north_az = np.nonzero(np.isclose(power_beam.axis1_array, np.pi / 2))

east_ind = np.nonzero(
power_beam.polarization_array
== utils.polstr2num("ee", x_orientation=power_beam.x_orientation)
)
north_ind = np.nonzero(
power_beam.polarization_array
== utils.polstr2num("nn", x_orientation=power_beam.x_orientation)
)

# check that the e/w dipole is more sensitive n/s
assert (
power_beam.data_array[0, east_ind, 0, za_val, east_az]
< power_beam.data_array[0, east_ind, 0, za_val, north_az]
)

# check that the n/s dipole is more sensitive e/w
assert (
power_beam.data_array[0, north_ind, 0, za_val, north_az]
< power_beam.data_array[0, north_ind, 0, za_val, east_az]
)

# check that for a single dipole (all others turned off) there is higher
# azimuth-aligned response near the horizon than zenith angle-aligned response
# for both feed orientations
# this is true with all dipoles on too, but the difference is bigger for a
# single dipole
delays = np.full((2, 16), 32, dtype=int)
delays[:, 5] = 0
efield_beam = UVBeam.from_file(filename, pixels_per_deg=1, delays=delays)

za_val = np.nonzero(np.isclose(efield_beam.axis2_array, 80.0 * np.pi / 180))

max_az_response = np.max(np.abs(efield_beam.data_array[0, east_ind, 0, za_val, :]))
max_za_response = np.max(np.abs(efield_beam.data_array[1, east_ind, 0, za_val, :]))
assert max_az_response > max_za_response

max_az_response = np.max(np.abs(efield_beam.data_array[0, north_ind, 0, za_val, :]))
max_za_response = np.max(np.abs(efield_beam.data_array[1, north_ind, 0, za_val, :]))
assert max_az_response > max_za_response


def test_freq_range(mwa_beam_1ppd):
beam1 = mwa_beam_1ppd
beam2 = UVBeam()
Expand Down
Loading