Repository: RadioAstronomySoftwareGroup/pyuvdata
Pull request #772 (2020-02-20 21:08:28)

Conjugate metadata object
<!--- Provide a general summary of your changes in the Title above -->

## Description
<!--- Describe your changes in detail -->
added an if check for `metadata_only` in `uvdata.conjugate_bls`
## Motivation and Context
<!--- Why is this change required? What problem does it solve? -->
<!--- If it fixes an open issue, please link to the issue here. If this PR closes an issue, put the word 'closes' before the issue link to auto-close the issue when the PR is merged. -->
Noticed I could not conjugate a metadata only object, and this sounded useful for a personal project.
## Types of changes
<!--- What types of changes does your code introduce? Put an `x` in all the boxes that apply: -->
- [x] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to change)
- [ ] Documentation change (documentation changes only)
- [ ] Version change
- [ ] Build or continuous integration change


## Checklist:
<!--- You may remove the checklists that don't apply to your change type(s) or just leave them empty -->
<!--- Go over all the following points, and replace the space with an `x` in all the boxes that apply. -->
<!--- If you're unsure about any of these, don't hesitate to ask. We're here to help! -->
- [x] I have read the [contribution guide](https://github.com/RadioAstronomySoftwareGroup/pyuvdata/blob/master/.github/CONTRIBUTING.md).
- [x] My code follows the code style of this project.

Bug fix checklist:
- [x] My fix includes a new test that breaks as a result of the bug (if possible).
- [x] All new and existing tests pass.
- [x] I  have updated the [CHANGELOG](https://github.com/RadioAstronomySoftwareGroup/pyuvdata/blob/master/CHANGELOG.md).


codecov[bot]: # [Codecov](https://codecov.io/gh/RadioAstronomySoftwareGroup/pyuvdata/pull/772?src=pr&el=h1) Report
> Merging [#772](https://codecov.io/gh/RadioAstronomySoftwareGroup/pyuvdata/pull/772?src=pr&el=desc) into [master](https://codecov.io/gh/RadioAstronomySoftwareGroup/pyuvdata/commit/700c12e9667816a16990962c3c84e302e52bd46e&el=desc) will **increase** coverage by `0.00%`.
> The diff coverage is `n/a`.

[![Impacted file tree graph](https://codecov.io/gh/RadioAstronomySoftwareGroup/pyuvdata/pull/772/graphs/tree.svg?width=650&height=150&src=pr&token=4QykcCeB1H)](https://codecov.io/gh/RadioAstronomySoftwareGroup/pyuvdata/pull/772?src=pr&el=tree)

```diff
@@           Coverage Diff           @@
##           master     #772   +/-   ##
=======================================
  Coverage   98.93%   98.93%           
=======================================
  Files          26       26           
  Lines        9428     9429    +1     
=======================================
+ Hits         9328     9329    +1     
  Misses        100      100           
```



------

[Continue to review full report at Codecov](https://codecov.io/gh/RadioAstronomySoftwareGroup/pyuvdata/pull/772?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/RadioAstronomySoftwareGroup/pyuvdata/pull/772?src=pr&el=footer). Last update [700c12e...5c0b491](https://codecov.io/gh/RadioAstronomySoftwareGroup/pyuvdata/pull/772?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).


Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 72dddac3..2dfee808 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,7 @@ All notable changes to this project will be documented in this file.
 ## [Unreleased]
 
 ### Changed
+- UVData allows conjugation of metadata only objects.
 - Handling of strings in UVFlag files has been made more widely compatible.
 
 ## [2.0.0] - 2020-2-12
diff --git a/pyuvdata/uvdata/uvdata.py b/pyuvdata/uvdata/uvdata.py
index c85b6490..86a74633 100644
--- a/pyuvdata/uvdata/uvdata.py
+++ b/pyuvdata/uvdata/uvdata.py
@@ -1144,11 +1144,12 @@ class UVData(UVBase):
             new_pol_inds = uvutils.reorder_conj_pols(self.polarization_array)
 
             self.uvw_array[index_array] *= (-1)
-            orig_data_array = copy.copy(self.data_array)
 
-            for pol_ind in np.arange(self.Npols):
-                self.data_array[index_array, :, :, new_pol_inds[pol_ind]] = \
-                    np.conj(orig_data_array[index_array, :, :, pol_ind])
+            if not self.metadata_only:
+                orig_data_array = copy.copy(self.data_array)
+                for pol_ind in np.arange(self.Npols):
+                    self.data_array[index_array, :, :, new_pol_inds[pol_ind]] = \
+                        np.conj(orig_data_array[index_array, :, :, pol_ind])
 
             ant_1_vals = self.ant_1_array[index_array]
             ant_2_vals = self.ant_2_array[index_array]


Test patch:
diff --git a/pyuvdata/uvdata/tests/test_uvdata.py b/pyuvdata/uvdata/tests/test_uvdata.py
index 3cb493b1..a3a8f24c 100644
--- a/pyuvdata/uvdata/tests/test_uvdata.py
+++ b/pyuvdata/uvdata/tests/test_uvdata.py
@@ -1440,12 +1440,15 @@ def test_select_not_inplace():
     assert uv1 == uv_object
 
 
+@pytest.mark.parametrize("metadata_only", [True, False])
 @pytest.mark.filterwarnings("ignore:Telescope EVLA is not")
-def test_conjugate_bls():
+def test_conjugate_bls(metadata_only):
     uv1 = UVData()
     testfile = os.path.join(DATA_PATH, 'day2_TDEM0003_10s_norx_1src_1spw.uvfits')
-    uv1.read_uvfits(testfile)
 
+    uv1.read_uvfits(testfile, read_data=not(metadata_only))
+    if metadata_only:
+        assert uv1.metadata_only
     # file comes in with ant1<ant2
     assert(np.min(uv1.ant_2_array - uv1.ant_1_array) >= 0)
 
@@ -1459,19 +1462,20 @@ def test_conjugate_bls():
     assert(np.allclose(uv1.uvw_array, -1 * uv2.uvw_array,
                        rtol=uv1._uvw_array.tols[0], atol=uv1._uvw_array.tols[1]))
 
-    # complicated because of the polarization swaps
-    # polarization_array = [-1 -2 -3 -4]
-    assert(np.allclose(uv1.data_array[:, :, :, :2],
-                       np.conj(uv2.data_array[:, :, :, :2]),
-                       rtol=uv1._data_array.tols[0], atol=uv1._data_array.tols[1]))
+    if not metadata_only:
+        # complicated because of the polarization swaps
+        # polarization_array = [-1 -2 -3 -4]
+        assert(np.allclose(uv1.data_array[:, :, :, :2],
+                           np.conj(uv2.data_array[:, :, :, :2]),
+                           rtol=uv1._data_array.tols[0], atol=uv1._data_array.tols[1]))
 
-    assert(np.allclose(uv1.data_array[:, :, :, 2],
-                       np.conj(uv2.data_array[:, :, :, 3]),
-                       rtol=uv1._data_array.tols[0], atol=uv1._data_array.tols[1]))
+        assert(np.allclose(uv1.data_array[:, :, :, 2],
+                           np.conj(uv2.data_array[:, :, :, 3]),
+                           rtol=uv1._data_array.tols[0], atol=uv1._data_array.tols[1]))
 
-    assert(np.allclose(uv1.data_array[:, :, :, 3],
-                       np.conj(uv2.data_array[:, :, :, 2]),
-                       rtol=uv1._data_array.tols[0], atol=uv1._data_array.tols[1]))
+        assert(np.allclose(uv1.data_array[:, :, :, 3],
+                           np.conj(uv2.data_array[:, :, :, 2]),
+                           rtol=uv1._data_array.tols[0], atol=uv1._data_array.tols[1]))
 
     # check everything returned to original values with original convention
     uv2.conjugate_bls(convention='ant1<ant2')
@@ -1493,29 +1497,29 @@ def test_conjugate_bls():
     assert(np.allclose(uv1.uvw_array[blts_not_conjugated],
                        uv2.uvw_array[blts_not_conjugated],
                        rtol=uv1._uvw_array.tols[0], atol=uv1._uvw_array.tols[1]))
-
-    # complicated because of the polarization swaps
-    # polarization_array = [-1 -2 -3 -4]
-    assert(np.allclose(uv1.data_array[blts_to_conjugate, :, :, :2],
-                       np.conj(uv2.data_array[blts_to_conjugate, :, :, :2]),
-                       rtol=uv1._data_array.tols[0], atol=uv1._data_array.tols[1]))
-    assert(np.allclose(uv1.data_array[blts_not_conjugated, :, :, :2],
-                       uv2.data_array[blts_not_conjugated, :, :, :2],
-                       rtol=uv1._data_array.tols[0], atol=uv1._data_array.tols[1]))
-
-    assert(np.allclose(uv1.data_array[blts_to_conjugate, :, :, 2],
-                       np.conj(uv2.data_array[blts_to_conjugate, :, :, 3]),
-                       rtol=uv1._data_array.tols[0], atol=uv1._data_array.tols[1]))
-    assert(np.allclose(uv1.data_array[blts_not_conjugated, :, :, 2],
-                       uv2.data_array[blts_not_conjugated, :, :, 2],
-                       rtol=uv1._data_array.tols[0], atol=uv1._data_array.tols[1]))
-
-    assert(np.allclose(uv1.data_array[blts_to_conjugate, :, :, 3],
-                       np.conj(uv2.data_array[blts_to_conjugate, :, :, 2]),
-                       rtol=uv1._data_array.tols[0], atol=uv1._data_array.tols[1]))
-    assert(np.allclose(uv1.data_array[blts_not_conjugated, :, :, 3],
-                       uv2.data_array[blts_not_conjugated, :, :, 3],
-                       rtol=uv1._data_array.tols[0], atol=uv1._data_array.tols[1]))
+    if not metadata_only:
+        # complicated because of the polarization swaps
+        # polarization_array = [-1 -2 -3 -4]
+        assert(np.allclose(uv1.data_array[blts_to_conjugate, :, :, :2],
+                           np.conj(uv2.data_array[blts_to_conjugate, :, :, :2]),
+                           rtol=uv1._data_array.tols[0], atol=uv1._data_array.tols[1]))
+        assert(np.allclose(uv1.data_array[blts_not_conjugated, :, :, :2],
+                           uv2.data_array[blts_not_conjugated, :, :, :2],
+                           rtol=uv1._data_array.tols[0], atol=uv1._data_array.tols[1]))
+
+        assert(np.allclose(uv1.data_array[blts_to_conjugate, :, :, 2],
+                           np.conj(uv2.data_array[blts_to_conjugate, :, :, 3]),
+                           rtol=uv1._data_array.tols[0], atol=uv1._data_array.tols[1]))
+        assert(np.allclose(uv1.data_array[blts_not_conjugated, :, :, 2],
+                           uv2.data_array[blts_not_conjugated, :, :, 2],
+                           rtol=uv1._data_array.tols[0], atol=uv1._data_array.tols[1]))
+
+        assert(np.allclose(uv1.data_array[blts_to_conjugate, :, :, 3],
+                           np.conj(uv2.data_array[blts_to_conjugate, :, :, 2]),
+                           rtol=uv1._data_array.tols[0], atol=uv1._data_array.tols[1]))
+        assert(np.allclose(uv1.data_array[blts_not_conjugated, :, :, 3],
+                           uv2.data_array[blts_not_conjugated, :, :, 3],
+                           rtol=uv1._data_array.tols[0], atol=uv1._data_array.tols[1]))
 
     # check uv half plane conventions
     uv2.conjugate_bls(convention='u<0', use_enu=False)