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

Add a UVBeam.new() method similar to the ones on UVData and UVCal #1378

Merged
merged 3 commits into from
Jan 23, 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
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,14 @@ All notable changes to this project will be documented in this file.
## [Unreleased]

### Added
- A new `freq_interp_kind` parameter to `UVBeam.interp`, `UVBeam._interp_az_za_rect_spline`
and `UVBeam._interp_healpix_bilinear` to allow the frequency interpolation
specification to be passed into the methods. Note this defaults to "cubic" rather
than "linear" (the old default for the attribute of the same name on UVBeam objects)
because several groups have found that a linear interpolation leads to nasty
artifacts in visibility simulations for EoR applications.
- A new `UVBeam.new()` method (based on new function `new_uvbeam`) that creates a new,
self-consistent `UVBeam` object from scratch from a set of flexible input parameters.
- Added a the `UVData.update_antenna_positions` method to enable making antenna
position updates with corresponding updates the uvw-coordinates and visibility phases.
- Added a switch to `UVData.write_ms` called `flip_conj`, which allows a user to write
Expand Down Expand Up @@ -32,6 +40,12 @@ tolerance value to be user-specified.
Additionally, failing this check results in a warning (was an error).

### Deprecated
- The `freq_interp_kind` attribute on UVBeams.
- The `spw_array` and `Nspws` attributes on UVBeam objects. Also the
`unset_spw_params` and `set_spw_params` parameters to the `use_future_array_shapes`
and `use_current_array_shapes` methods on UVBeam objects.
- Upper case feed names (e.g. "N" or "E") in UVBeam.feed_array. This was never
fully tested and didn't work properly.
- Having `freq_range` defined on non-wide-band gain style UVCal objects.
- Having `freq_array` and `channel_width` defined on wide-band UVCal objects.

Expand Down
31 changes: 31 additions & 0 deletions docs/uvbeam_tutorial.rst
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,37 @@ See :ref:`uvbeam_to_healpix` for more details on the :meth:`pyuvdata.UVBeam.to_h
>>> write_file = os.path.join('.', 'tutorial.fits')
>>> beam.write_beamfits(write_file, clobber=True)


UVBeam: Instantiating from arrays in memory
-------------------------------------------
``pyuvdata`` can also be used to create a UVBeam object from arrays in memory. This
is useful for mocking up data for testing or for creating a UVBeam object from
simulated data. Instead of instantiating a blank object and setting each required
parameter, you can use the ``.new()`` static method, which deals with the task
of creating a consistent object from a minimal set of inputs

.. code-block:: python

>>> from pyuvdata import UVBeam
>>> from astropy.coordinates import EarthLocation
>>> import numpy as np
>>> uvb = UVBeam.new(
... telescope_name="test",
... data_normalization="physical",
... freq_array=np.linspace(100e6, 200e6, 10),
... x_orientation = "east",
... feed_array = ["e", "n"],
... axis1_array=np.deg2rad(np.linspace(-180, 179, 360)),
... axis2_array=np.deg2rad(np.linspace(0, 90, 181)),
... )

Notice that you need only provide the required parameters, and the rest will be
filled in with sensible defaults.

See the full documentation for the method
:func:`pyuvdata.uvbeam.UVBeam.new` for more information.


UVBeam: Selecting data
----------------------
The :meth:`pyuvdata.UVBeam.select` method lets you select specific image axis indices
Expand Down
36 changes: 36 additions & 0 deletions docs/uvcal_tutorial.rst
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,42 @@ data-like arrays as well, filled with zeros.
[ 0 1 11 12 13 23 24 25]


UVCal: Instantiating from arrays in memory
------------------------------------------
``pyuvdata`` can also be used to create a UVCal object from arrays in memory. This
is useful for mocking up data for testing or for creating a UVCal object from
simulated data. Instead of instantiating a blank object and setting each required
parameter, you can use the ``.new()`` static method, which deals with the task
of creating a consistent object from a minimal set of inputs

.. code-block:: python

>>> from pyuvdata import UVCal
>>> from astropy.coordinates import EarthLocation
>>> import numpy as np
>>> uvc = UVCal.new(
... gain_convention = "multiply",
... x_orientation = "east",
... cal_style = "redundant",
... freq_array = np.linspace(1e8, 2e8, 100),
... jones_array = ["ee", "nn"],
... antenna_positions = {
... 0: [0.0, 0.0, 0.0],
... 1: [0.0, 0.0, 1.0],
... 2: [0.0, 0.0, 2.0],
... },
... telescope_location = EarthLocation.from_geodetic(0, 0, 0),
... telescope_name = "test",
... time_array = np.linspace(2459855, 2459856, 20),
... )

Notice that you need only provide the required parameters, and the rest will be
filled in with sensible defaults.

See the full documentation for the method
:func:`pyuvdata.uvcal.UVCal.new` for more information.


UVCal: Quick data access
------------------------
Method for quick data access, similar to those on :class:`pyuvdata.UVData`
Expand Down
17 changes: 1 addition & 16 deletions pyuvdata/uvbeam/beamfits.py
Original file line number Diff line number Diff line change
Expand Up @@ -253,9 +253,6 @@ def read_beamfits(
"UVBeam does not support having a spectral window axis "
"larger than one."
)
if not use_future_array_shapes:
self.Nspws = 1
self.spw_array = np.array([0])

if n_dimensions > ax_nums["basisvec"] - 1:
if (
Expand All @@ -268,12 +265,7 @@ def read_beamfits(
"NAXIS" + str(ax_nums["basisvec"]), None
)

if (
self.Nspws is None or self.Naxes_vec is None
) and self.beam_type == "power":
if self.Nspws is None and not use_future_array_shapes:
self.Nspws = 1
self.spw_array = np.array([0])
if self.Naxes_vec is None and self.beam_type == "power":
if self.Naxes_vec is None:
self.Naxes_vec = 1

Expand Down Expand Up @@ -365,7 +357,6 @@ def read_beamfits(
self.model_name = primary_header.pop("MODEL", None)
self.model_version = primary_header.pop("MODELVER", None)
self.x_orientation = primary_header.pop("XORIENT", None)
self.freq_interp_kind = primary_header.pop("FINTERP", None)

self.history = str(primary_header.get("HISTORY", ""))
if not uvutils._check_history_version(
Expand Down Expand Up @@ -663,12 +654,6 @@ def write_beamfits(
if self.x_orientation is not None:
primary_header["XORIENT"] = self.x_orientation

if self.freq_interp_kind is not None:
primary_header["FINTERP"] = (
self.freq_interp_kind,
"frequency " "interpolation kind (scipy interp1d)",
)

if self.beam_type == "efield":
primary_header["FEEDLIST"] = "[" + ", ".join(self.feed_array) + "]"

Expand Down
3 changes: 0 additions & 3 deletions pyuvdata/uvbeam/cst_beam.py
Original file line number Diff line number Diff line change
Expand Up @@ -200,9 +200,6 @@ def read_cst_beam(
self.freq_array = np.zeros((1, self.Nfreqs))
self.bandpass_array = np.zeros((1, self.Nfreqs))

if not use_future_array_shapes:
self.Nspws = 1
self.spw_array = np.array([0])
self.pixel_coordinate_system = "az_za"
self._set_cs_params()

Expand Down
Loading
Loading