Skip to content

Commit

Permalink
refactor the uvbeam._convert_feeds_to_pols into a utility function
Browse files Browse the repository at this point in the history
To enable wider use of the function (specifically in pyuvsim)
  • Loading branch information
bhazelton committed Feb 25, 2025
1 parent f1bb13c commit ed76254
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 28 deletions.
4 changes: 2 additions & 2 deletions src/pyuvdata/analytic_beam.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

from . import utils
from .docstrings import combine_docstrings
from .uvbeam.uvbeam import UVBeam, _convert_feeds_to_pols
from .uvbeam.uvbeam import UVBeam

__all__ = ["AnalyticBeam", "AiryBeam", "GaussianBeam", "ShortDipoleBeam", "UniformBeam"]

Expand Down Expand Up @@ -164,7 +164,7 @@ def __post_init__(self, include_cross_pols):
if len(self.feed_array) == 1:
include_cross_pols = False

self.polarization_array, _ = _convert_feeds_to_pols(
self.polarization_array = utils.convert_feeds_to_pols(
self.feed_array, include_cross_pols, x_orientation=self.x_orientation
)

Expand Down
53 changes: 53 additions & 0 deletions src/pyuvdata/utils/pol.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from functools import lru_cache, wraps

import numpy as np
import numpy.typing as npt

from . import tools

Expand All @@ -27,6 +28,7 @@
"x_orientation_pol_map",
"parse_polstr",
"parse_jpolstr",
"convert_feeds_to_pols",
]

# fmt: off
Expand Down Expand Up @@ -531,6 +533,57 @@ def determine_pol_order(pols, *, order="AIPS"):
return index_array


def convert_feeds_to_pols(
feed_array: npt.NDArray[str],
include_cross_pols: bool = True,
x_orientation: str | None = None,
return_feed_pol_order: bool = False,
):
"""
Get the polarizations given a feed array.
Parameters
----------
feed_array : ndarray of str
Array of feed orientations. Options are: n/e or x/y or r/l.
include_cross_pols : bool
Option to include the cross polarizations (e.g. xy and yx or en and ne).
Defaults to True if more than one feed, set to False for only one feed.
x_orientation : str, optional
Orientation of the x-axis. Options are 'east', 'north', 'e', 'n', 'ew', 'ns'.
return_feed_pol_order : bool
Option to return a list of tuples giving the ordering of the feeds for
each pol. Default False.
"""
n_feeds = np.asarray(feed_array).size

if n_feeds < 1 or n_feeds > 2:
raise ValueError(
"feed_array contains {n_feeds}. Only 1 or 2 feeds is supported."
)

feed_pol_order = [(0, 0)]
if n_feeds > 1:
feed_pol_order.append((1, 1))
else:
include_cross_pols = False

if include_cross_pols:
feed_pol_order.extend([(0, 1), (1, 0)])

pol_strings = []
for pair in feed_pol_order:
pol_strings.append(feed_array[pair[0]] + feed_array[pair[1]])
polarization_array = np.array(
[polstr2num(ps.upper(), x_orientation=x_orientation) for ps in pol_strings]
)
if return_feed_pol_order:
return polarization_array, feed_pol_order
else:
return polarization_array


def _select_pol_helper(
polarizations,
obj_pol_array,
Expand Down
2 changes: 1 addition & 1 deletion src/pyuvdata/uvbeam/initializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def new_uvbeam(
feed_version: str = "0.0",
model_name: str = "default",
model_version: str = "0.0",
feed_array: npt.NDArray[np.str] | None = None,
feed_array: npt.NDArray[str] | None = None,
polarization_array: (
npt.NDArray[np.str | np.int] | list[str | int] | tuple[str | int] | None
) = None,
Expand Down
28 changes: 3 additions & 25 deletions src/pyuvdata/uvbeam/uvbeam.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,29 +22,6 @@
__all__ = ["UVBeam"]


def _convert_feeds_to_pols(feed_array, calc_cross_pols, x_orientation=None):
n_feeds = np.asarray(feed_array).size

feed_pol_order = [(0, 0)]
if n_feeds > 1:
feed_pol_order.append((1, 1))

if calc_cross_pols:
# to get here we have Nfeeds > 1
feed_pol_order.extend([(0, 1), (1, 0)])

pol_strings = []
for pair in feed_pol_order:
pol_strings.append(feed_array[pair[0]] + feed_array[pair[1]])
polarization_array = np.array(
[
utils.polstr2num(ps.upper(), x_orientation=x_orientation)
for ps in pol_strings
]
)
return polarization_array, feed_pol_order


class UVBeam(UVBase):
"""
A class for defining a radio telescope antenna beam.
Expand Down Expand Up @@ -927,10 +904,11 @@ def efield_to_power(
# There are no cross pols with one feed. Set this so the power beam is real
calc_cross_pols = False

beam_object.polarization_array, feed_pol_order = _convert_feeds_to_pols(
beam_object.polarization_array, feed_pol_order = utils.convert_feeds_to_pols(
beam_object.feed_array,
calc_cross_pols,
include_cross_pols=calc_cross_pols,
x_orientation=beam_object.x_orientation,
return_feed_pol_order=True,
)
beam_object.Npols = beam_object.polarization_array.size

Expand Down

0 comments on commit ed76254

Please sign in to comment.