Repository: RadioAstronomySoftwareGroup/pyuvdata
Pull request #710 (2019-10-31 22:53:13)

Add equalization coefficients and refactor tests
## Description
This PR adds an `eq_coeffs` parameter to UVData objects to store equalization coefficients. It also adds a method for removing them from the data.

## Motivation and Context
Because they are arrays (of size `(Nants_antenna, Nfreqs)`), the `eq_coeffs` cannot be saved as an extra parameter. They are added as an optional parameter on UVData objects, with support for reading/writing them from uvh5 files. Support for writing them to other file formats is saved for future work.

I also got a little carried away and refactored the `test_uvh5.py` suite to make use of fixtures for common files and breaking giant tests into multiple smaller ones. Apologies for mixing multiple changesets into a single PR.

## Types of changes
<!--- What types of changes does your code introduce? Put an `x` in all the boxes that apply: -->
- [ ] Bug fix (non-breaking change which fixes an issue)
- [x] 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.

New feature checklist:
- [x] I have added or updated the docstrings associated with my feature using the [numpy docstring format](https://numpydoc.readthedocs.io/en/latest/format.html).
- [ ] I have updated the tutorial to highlight my new feature (if appropriate).
- [x] I have added tests to cover my new feature.
- [x] All new and existing tests pass in both python 2 and python 3.
- [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/710?src=pr&el=h1) Report
> Merging [#710](https://codecov.io/gh/RadioAstronomySoftwareGroup/pyuvdata/pull/710?src=pr&el=desc) into [master](https://codecov.io/gh/RadioAstronomySoftwareGroup/pyuvdata/commit/da98deb56f1bcf85585112709840816ff0ed64df?src=pr&el=desc) will **decrease** coverage by `0.06%`.
> The diff coverage is `100%`.

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

```diff
@@            Coverage Diff             @@
##           master     #710      +/-   ##
==========================================
- Coverage      99%   98.93%   -0.07%     
==========================================
  Files          20       20              
  Lines        9119     9142      +23     
==========================================
+ Hits         9028     9045      +17     
- Misses         91       97       +6
```


| [Impacted Files](https://codecov.io/gh/RadioAstronomySoftwareGroup/pyuvdata/pull/710?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [pyuvdata/uvh5.py](https://codecov.io/gh/RadioAstronomySoftwareGroup/pyuvdata/pull/710/diff?src=pr&el=tree#diff-cHl1dmRhdGEvdXZoNS5weQ==) | `98.79% <100%> (-1.21%)` | :arrow_down: |
| [pyuvdata/uvdata.py](https://codecov.io/gh/RadioAstronomySoftwareGroup/pyuvdata/pull/710/diff?src=pr&el=tree#diff-cHl1dmRhdGEvdXZkYXRhLnB5) | `100% <100%> (ø)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/RadioAstronomySoftwareGroup/pyuvdata/pull/710?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/710?src=pr&el=footer). Last update [da98deb...a1d4ddb](https://codecov.io/gh/RadioAstronomySoftwareGroup/pyuvdata/pull/710?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

plaplant: Excellent point, I’ll add that change. We do that with calfits for instance.

Sent from my iPhone

> On Nov 1, 2019, at 14:07, Bryna Hazelton <notifications@github.com> wrote:
> 
> ﻿
> @bhazelton commented on this pull request.
> 
> Looking good, just one comment about the eq convention. I did go look at uvfits and miriad and I don't see a natural place that this fits into those file formats. We can certainly look more and even explore adding non-canonical things -- we've done that in the past with uvfits (lst_array) and it hasn't broken other readers because the file formats are fairly well designed. But I don't think that needs to happen in this PR.
> 
> In pyuvdata/uvdata.py:
> 
> > @@ -5194,3 +5202,53 @@ def resample_in_time(self, target_time, only_downsample=False, only_upsample=Fal
>              )
>  
>          return
> +
> +    def remove_eq_coeffs(self, convention="divide"):
> Should the convention be stored on the object (and in the file) along with the coefficients? Otherwise the user has to know the convention.
> 
> —
> You are receiving this because you authored the thread.
> Reply to this email directly, view it on GitHub, or unsubscribe.

bhazelton: Once this is merged, I'm going to get you to rebase the `add_rephasing` branch @plaplant so you can sort out the merge conflicts in `test_uvh5.py`. I'm certain there will be some.

Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index c38de898..45316c8b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,7 @@ All notable changes to this project will be documented in this file.
 ## [Unreleased]
 
 ### Added
+- `eq_coeffs` for storing equalization coefficients and `remove_eq_coeffs` for removing them.
 - `utils.apply_uvflag` for applying UVFlag objects to UVData objects
 
 ### Fixed
diff --git a/pyuvdata/uvdata.py b/pyuvdata/uvdata.py
index d3c87160..90643b6f 100644
--- a/pyuvdata/uvdata.py
+++ b/pyuvdata/uvdata.py
@@ -363,6 +363,21 @@ class UVData(UVBase):
                                                        description=desc,
                                                        spoof_val=0)
 
+        desc = "Per-antenna and per-frequency equalization coefficients"
+        self._eq_coeffs = uvp.UVParameter("eq_coeffs",
+                                          required=False,
+                                          description=desc,
+                                          form=("Nants_telescope", "Nfreqs"),
+                                          expected_type=np.float,
+                                          spoof_val=1.0)
+
+        desc = "Convention for how to remove eq_coeffs from data"
+        self._eq_coeffs_convention = uvp.UVParameter("eq_coeffs_convention",
+                                                     required=False,
+                                                     description=desc,
+                                                     form="str",
+                                                     spoof_val="divide")
+
         super(UVData, self).__init__()
 
     @property
@@ -5194,3 +5209,62 @@ class UVData(UVBase):
             )
 
         return
+
+    def remove_eq_coeffs(self):
+        """Remove equalization coefficients from the data.
+
+        Some telescopes, e.g. HERA, apply per-antenna, per-frequency gain
+        coefficients as part of the signal chain. These are stored in the
+        `eq_coeffs` attribute of the object. This method will remove them, so
+        that the data are in "unnormalized" raw units.
+
+        Parameters
+        ----------
+        None
+
+        Returns
+        -------
+        None
+
+        Raises
+        ------
+        ValueError
+            Raised if eq_coeffs or eq_coeffs_convention are not defined on the
+            object, or if eq_coeffs_convention is not one of "multiply" or "divide".
+        """
+        if self.eq_coeffs is None:
+            raise ValueError(
+                "The eq_coeffs attribute must be defined on the object to apply them."
+            )
+        if self.eq_coeffs_convention is None:
+            raise ValueError(
+                "The eq_coeffs_convention attribute must be defined on the object "
+                "to apply them."
+            )
+        if self.eq_coeffs_convention not in ("multiply", "divide"):
+            raise ValueError(
+                "Got unknown convention {}. Must be one of: "
+                '"multiply", "divide"'.format(self.eq_coeffs_convention)
+            )
+
+        # apply coefficients for each baseline
+        for key in self.get_antpairs():
+            # get indices for this key
+            blt_inds = self.antpair2ind(key)
+
+            ant1_index = np.asarray(self.antenna_numbers == key[0]).nonzero()[0][0]
+            ant2_index = np.asarray(self.antenna_numbers == key[1]).nonzero()[0][0]
+
+            eq_coeff1 = self.eq_coeffs[ant1_index, :]
+            eq_coeff2 = self.eq_coeffs[ant2_index, :]
+
+            # make sure coefficients are the right size to broadcast
+            eq_coeff1 = np.repeat(eq_coeff1[:, np.newaxis], self.Npols, axis=1)
+            eq_coeff2 = np.repeat(eq_coeff2[:, np.newaxis], self.Npols, axis=1)
+
+            if self.eq_coeffs_convention == "multiply":
+                self.data_array[blt_inds, 0, :, :] *= eq_coeff1 * eq_coeff2
+            else:
+                self.data_array[blt_inds, 0, :, :] /= eq_coeff1 * eq_coeff2
+
+        return
diff --git a/pyuvdata/uvh5.py b/pyuvdata/uvh5.py
index 70c8eb16..d3705fa8 100644
--- a/pyuvdata/uvh5.py
+++ b/pyuvdata/uvh5.py
@@ -61,13 +61,13 @@ def _check_uvh5_dtype(dtype):
         None
     """
     if not isinstance(dtype, np.dtype):
-        raise ValueError("dtype in a uvh5 must be a numpy dtype")
+        raise ValueError("dtype in a uvh5 file must be a numpy dtype")
     if 'r' not in dtype.names or 'i' not in dtype.names:
-        raise ValueError("datatype must be be a compound datatype with an 'r' field and an 'i' field")
+        raise ValueError("dtype must be a compound datatype with an 'r' field and an 'i' field")
     rkind = dtype['r'].kind
     ikind = dtype['i'].kind
     if rkind != ikind:
-        raise ValueError("datatype must have the same kind ('i4', 'r8', etc.) for both real and imaginary fields")
+        raise ValueError("dtype must have the same kind ('i4', 'r8', etc.) for both real and imaginary fields")
     return
 
 
@@ -198,6 +198,12 @@ class UVH5(UVData):
             self.antenna_diameters = header['antenna_diameters'][()]
         if 'uvplane_reference_time' in header:
             self.uvplane_reference_time = int(header['uvplane_reference_time'][()])
+        if 'eq_coeffs' in header:
+            self.eq_coeffs = header['eq_coeffs'][()]
+        if 'eq_coeffs_convention' in header:
+            self.eq_coeffs_convention = _read_uvh5_string(
+                header['eq_coeffs_convention'], filename
+            )
 
         # check for phasing information
         self.phase_type = _read_uvh5_string(header['phase_type'], filename)
@@ -583,6 +589,10 @@ class UVH5(UVData):
             header['antenna_diameters'] = self.antenna_diameters
         if self.uvplane_reference_time is not None:
             header['uvplane_reference_time'] = self.uvplane_reference_time
+        if self.eq_coeffs is not None:
+            header['eq_coeffs'] = self.eq_coeffs
+        if self.eq_coeffs_convention is not None:
+            header['eq_coeffs_convention'] = np.string_(self.eq_coeffs_convention)
 
         # write out extra keywords if it exists and has elements
         if self.extra_keywords:
@@ -812,7 +822,7 @@ class UVH5(UVData):
             del uvd_file
         return
 
-    def write_uvh5_part(self, filename, data_array, flags_array, nsample_array, check_header=True,
+    def write_uvh5_part(self, filename, data_array, flag_array, nsample_array, check_header=True,
                         antenna_nums=None, antenna_names=None, ant_str=None, bls=None,
                         frequencies=None, freq_chans=None, times=None, polarizations=None,
                         blt_inds=None, run_check_acceptability=True, add_to_history=None):
@@ -825,7 +835,7 @@ class UVH5(UVData):
             data_array: the data to write to disk. A check is done to ensure that
                 the dimensions of the data passed in conform to the ones specified by
                 the "selection" arguments.
-            flags_array: the flags array to write to disk. A check is done to ensure
+            flag_array: the flags array to write to disk. A check is done to ensure
                 that the dimensions of the data passed in conform to the ones specified
                 by the "selection" arguments.
             nsample_array: the nsample array to write to disk. A check is done to ensure
@@ -892,8 +902,8 @@ class UVH5(UVData):
             polarizations, blt_inds)
 
         # make sure that the dimensions of the data to write are correct
-        if data_array.shape != flags_array.shape:
-            raise AssertionError("data_array and flags_array must have the same shape")
+        if data_array.shape != flag_array.shape:
+            raise AssertionError("data_array and flag_array must have the same shape")
         if data_array.shape != nsample_array.shape:
             raise AssertionError("data_array and nsample_array must have the same shape")
 
@@ -984,7 +994,7 @@ class UVH5(UVData):
                     _write_complex_astype(data_array, visdata_dset, indices)
                 else:
                     visdata_dset[blt_inds, :, freq_inds, pol_inds] = data_array
-                flags_dset[blt_inds, :, freq_inds, pol_inds] = flags_array
+                flags_dset[blt_inds, :, freq_inds, pol_inds] = flag_array
                 nsamples_dset[blt_inds, :, freq_inds, pol_inds] = nsample_array
             elif n_reg_spaced == 1:
                 # figure out which axis is regularly spaced
@@ -996,7 +1006,7 @@ class UVH5(UVData):
                                 _write_complex_astype(data_array[:, :, ifreq, ipol], visdata_dset, indices)
                             else:
                                 visdata_dset[blt_inds, :, freq_idx, pol_idx] = data_array[:, :, ifreq, ipol]
-                            flags_dset[blt_inds, :, freq_idx, pol_idx] = flags_array[:, :, ifreq, ipol]
+                            flags_dset[blt_inds, :, freq_idx, pol_idx] = flag_array[:, :, ifreq, ipol]
                             nsamples_dset[blt_inds, :, freq_idx, pol_idx] = nsample_array[:, :, ifreq, ipol]
                 elif freq_reg_spaced:
                     for iblt, blt_idx in enumerate(blt_inds):
@@ -1006,7 +1016,7 @@ class UVH5(UVData):
                                 _write_complex_astype(data_array[iblt, :, :, ipol], visdata_dset, indices)
                             else:
                                 visdata_dset[blt_idx, :, freq_inds, pol_idx] = data_array[iblt, :, :, ipol]
-                            flags_dset[blt_idx, :, freq_inds, pol_idx] = flags_array[iblt, :, :, ipol]
+                            flags_dset[blt_idx, :, freq_inds, pol_idx] = flag_array[iblt, :, :, ipol]
                             nsamples_dset[blt_idx, :, freq_inds, pol_idx] = nsample_array[iblt, :, :, ipol]
                 else:  # pol_reg_spaced
                     for iblt, blt_idx in enumerate(blt_inds):
@@ -1016,7 +1026,7 @@ class UVH5(UVData):
                                 _write_complex_astype(data_array[iblt, :, ifreq, :], visdata_dset, indices)
                             else:
                                 visdata_dset[blt_idx, :, freq_idx, pol_inds] = data_array[iblt, :, ifreq, :]
-                            flags_dset[blt_idx, :, freq_idx, pol_inds] = flags_array[iblt, :, ifreq, :]
+                            flags_dset[blt_idx, :, freq_idx, pol_inds] = flag_array[iblt, :, ifreq, :]
                             nsamples_dset[blt_idx, :, freq_idx, pol_inds] = nsample_array[iblt, :, ifreq, :]
             else:
                 # all axes irregularly spaced
@@ -1029,7 +1039,7 @@ class UVH5(UVData):
                                 _write_complex_astype(data_array[iblt, :, ifreq, ipol], visdata_dset, indices)
                             else:
                                 visdata_dset[blt_idx, :, freq_idx, pol_idx] = data_array[iblt, :, ifreq, ipol]
-                            flags_dset[blt_idx, :, freq_idx, pol_idx] = flags_array[iblt, :, ifreq, ipol]
+                            flags_dset[blt_idx, :, freq_idx, pol_idx] = flag_array[iblt, :, ifreq, ipol]
                             nsamples_dset[blt_idx, :, freq_idx, pol_idx] = nsample_array[iblt, :, ifreq, ipol]
 
             # append to history if desired


Test patch:
diff --git a/pyuvdata/tests/test_uvdata.py b/pyuvdata/tests/test_uvdata.py
index 38e81c6c..3fb14bf6 100644
--- a/pyuvdata/tests/test_uvdata.py
+++ b/pyuvdata/tests/test_uvdata.py
@@ -61,14 +61,16 @@ def uvdata_props():
                         '_gst0', '_rdate', '_earth_omega', '_dut1',
                         '_timesys', '_uvplane_reference_time',
                         '_phase_center_ra', '_phase_center_dec',
-                        '_phase_center_epoch', '_phase_center_frame']
+                        '_phase_center_epoch', '_phase_center_frame',
+                        '_eq_coeffs', '_eq_coeffs_convention']
 
     extra_properties = ['extra_keywords', 'antenna_positions',
                         'x_orientation', 'antenna_diameters', 'blt_order', 'gst0',
                         'rdate', 'earth_omega', 'dut1', 'timesys',
                         'uvplane_reference_time',
                         'phase_center_ra', 'phase_center_dec',
-                        'phase_center_epoch', 'phase_center_frame']
+                        'phase_center_epoch', 'phase_center_frame',
+                        'eq_coeffs', 'eq_coeffs_convention']
 
     other_properties = ['telescope_location_lat_lon_alt',
                         'telescope_location_lat_lon_alt_degrees',
@@ -327,9 +329,11 @@ def test_ant2_array_not_in_antnums(uvdata_data):
 def test_converttofiletype(uvdata_data):
     fhd_obj = uvdata_data.uv_object._convert_to_filetype('fhd')
     uvdata_data.uv_object._convert_from_filetype(fhd_obj)
-    assert uvdata_data.uv_object, uvdata_data.uv_object2
+    assert uvdata_data.uv_object == uvdata_data.uv_object2
 
-    pytest.raises(ValueError, uvdata_data.uv_object._convert_to_filetype, 'foo')
+    with pytest.raises(ValueError) as cm:
+        uvdata_data.uv_object._convert_to_filetype('foo')
+    assert str(cm.value).startswith("filetype must be uvfits, miriad, fhd, or uvh5")
 
 
 @pytest.fixture(scope='function')
@@ -5496,3 +5500,77 @@ def test_resample_in_time_only_upsample(bda_test_file):
     assert np.isclose(init_data_136_137[0, 0, 0], out_data_136_137[0, 0, 0])
 
     return
+
+
+def test_remove_eq_coeffs_divide(uvdata_data):
+    """Test using the remove_eq_coeffs method with divide convention."""
+    # give eq_coeffs to the object
+    eq_coeffs = np.empty(
+        (uvdata_data.uv_object.Nants_telescope, uvdata_data.uv_object.Nfreqs),
+        dtype=np.float
+    )
+    for i, ant in enumerate(uvdata_data.uv_object.antenna_numbers):
+        eq_coeffs[i, :] = ant + 1
+    uvdata_data.uv_object.eq_coeffs = eq_coeffs
+    uvdata_data.uv_object.eq_coeffs_convention = "divide"
+    uvdata_data.uv_object.remove_eq_coeffs()
+
+    # make sure the right coefficients were removed
+    for key in uvdata_data.uv_object.get_antpairs():
+        eq1 = key[0] + 1
+        eq2 = key[1] + 1
+        blt_inds = uvdata_data.uv_object.antpair2ind(key)
+        norm_data = uvdata_data.uv_object.data_array[blt_inds, 0, :, :]
+        unnorm_data = uvdata_data.uv_object2.data_array[blt_inds, 0, :, :]
+        assert np.allclose(norm_data, unnorm_data / (eq1 * eq2))
+
+    return
+
+
+def test_remove_eq_coeffs_multiply(uvdata_data):
+    """Test using the remove_eq_coeffs method with multiply convention."""
+    # give eq_coeffs to the object
+    eq_coeffs = np.empty(
+        (uvdata_data.uv_object.Nants_telescope, uvdata_data.uv_object.Nfreqs),
+        dtype=np.float
+    )
+    for i, ant in enumerate(uvdata_data.uv_object.antenna_numbers):
+        eq_coeffs[i, :] = ant + 1
+    uvdata_data.uv_object.eq_coeffs = eq_coeffs
+    uvdata_data.uv_object.eq_coeffs_convention = "multiply"
+    uvdata_data.uv_object.remove_eq_coeffs()
+
+    # make sure the right coefficients were removed
+    for key in uvdata_data.uv_object.get_antpairs():
+        eq1 = key[0] + 1
+        eq2 = key[1] + 1
+        blt_inds = uvdata_data.uv_object.antpair2ind(key)
+        norm_data = uvdata_data.uv_object.data_array[blt_inds, 0, :, :]
+        unnorm_data = uvdata_data.uv_object2.data_array[blt_inds, 0, :, :]
+        assert np.allclose(norm_data, unnorm_data * (eq1 * eq2))
+
+    return
+
+
+def test_remove_eq_coeffs_errors(uvdata_data):
+    """Test errors raised by remove_eq_coeffs method."""
+    # raise error when eq_coeffs are not defined
+    with pytest.raises(ValueError) as cm:
+        uvdata_data.uv_object.remove_eq_coeffs()
+    assert str(cm.value).startswith("The eq_coeffs attribute must be defined")
+
+    # raise error when eq_coeffs are defined but not eq_coeffs_convention
+    uvdata_data.uv_object.eq_coeffs = np.ones(
+        (uvdata_data.uv_object.Nants_telescope, uvdata_data.uv_object.Nfreqs)
+    )
+    with pytest.raises(ValueError) as cm:
+        uvdata_data.uv_object.remove_eq_coeffs()
+    assert str(cm.value).startswith("The eq_coeffs_convention attribute must be defined")
+
+    # raise error when convention is not a valid choice
+    uvdata_data.uv_object.eq_coeffs_convention = "foo"
+    with pytest.raises(ValueError) as cm:
+        uvdata_data.uv_object.remove_eq_coeffs()
+    assert str(cm.value).startswith("Got unknown convention foo. Must be one of")
+
+    return
diff --git a/pyuvdata/tests/test_uvh5.py b/pyuvdata/tests/test_uvh5.py
index 5cb1d6ee..03b7c02f 100644
--- a/pyuvdata/tests/test_uvh5.py
+++ b/pyuvdata/tests/test_uvh5.py
@@ -9,7 +9,6 @@ from __future__ import absolute_import, division, print_function
 
 import os
 import six
-import copy
 import numpy as np
 import pytest
 from astropy.time import Time
@@ -22,17 +21,136 @@ import pyuvdata.tests as uvtest
 from pyuvdata.uvh5 import _hera_corr_dtype
 
 
-def test_ReadMiriadWriteUVH5ReadUVH5():
+# ignore common file-read warnings
+pytestmark = [
+    pytest.mark.filterwarnings("ignore:Altitude is not present in Miriad"),
+    pytest.mark.filterwarnings("ignore:Telescope EVLA is not"),
+]
+
+
+@pytest.fixture(scope="function")
+def uv_miriad():
+    # read in a miriad test file
+    uv_miriad = UVData()
+    miriad_filename = os.path.join(DATA_PATH, "zen.2456865.60537.xy.uvcRREAA")
+    uv_miriad.read_miriad(miriad_filename)
+    yield uv_miriad
+
+    # clean up when done
+    del uv_miriad
+
+    return
+
+
+@pytest.fixture(scope="function")
+def uv_uvfits():
+    # read in a uvfits test file
+    uv_uvfits = UVData()
+    uvfits_filename = os.path.join(DATA_PATH, "day2_TDEM0003_10s_norx_1src_1spw.uvfits")
+    uv_uvfits.read_uvfits(uvfits_filename)
+    yield uv_uvfits
+
+    # clean up when done
+    del uv_uvfits
+
+    return
+
+
+@pytest.fixture(scope="function")
+def uv_uvh5():
+    # read in a uvh5 test file
+    uv_uvh5 = UVData()
+    uvh5_filename = os.path.join(DATA_PATH, 'zen.2458432.34569.uvh5')
+    uv_uvh5.read_uvh5(uvh5_filename)
+    yield uv_uvh5
+
+    # clean up when done
+    del uv_uvh5
+
+    return
+
+
+@pytest.fixture(scope="function")
+def uv_partial_write():
+    # convert a uvfits file to uvh5, cutting down the amount of data
+    uv_uvfits = UVData()
+    uvfits_filename = os.path.join(DATA_PATH, "day2_TDEM0003_10s_norx_1src_1spw.uvfits")
+    uv_uvfits.read_uvfits(uvfits_filename)
+    uv_uvfits.select(antenna_nums=[3, 7, 24])
+    uv_uvfits.lst_array = uvutils.get_lst_for_time(
+        uv_uvfits.time_array, *uv_uvfits.telescope_location_lat_lon_alt_degrees
+    )
+
+    testfile = os.path.join(DATA_PATH, "test", "outtest.uvh5")
+    uv_uvfits.write_uvh5(testfile)
+    uv_uvh5 = UVData()
+    uv_uvh5.read(testfile)
+
+    yield uv_uvh5
+
+    # clean up when done
+    del uv_uvh5
+    os.remove(testfile)
+
+    return
+
+
+def initialize_with_zeros(uvd, filename):
     """
-    Miriad round trip test
+    Make a uvh5 file with all zero values for data-sized arrays.
+
+    This function is a helper function used for tests of partial writing.
     """
-    uv_in = UVData()
+    uvd.initialize_uvh5_file(filename, clobber=True)
+    data_shape = (uvd.Nblts, 1, uvd.Nfreqs, uvd.Npols)
+    data = np.zeros(data_shape, dtype=np.complex64)
+    flags = np.zeros(data_shape, dtype=np.bool)
+    nsamples = np.zeros(data_shape, dtype=np.float32)
+    with h5py.File(filename, 'r+') as h5f:
+        dgrp = h5f['/Data']
+        data_dset = dgrp['visdata']
+        flags_dset = dgrp['flags']
+        nsample_dset = dgrp['nsamples']
+        data_dset = data
+        flags_dset = flags
+        nsample_dset = nsamples
+    return
+
+
+def initialize_with_zeros_ints(uvd, filename):
+    """
+    Make a uvh5 file with all zeros for data-sized arrays.
+
+    This function is a helper function used for tests of partial writing with
+    integer data types.
+    """
+    uvd.initialize_uvh5_file(
+        filename, clobber=True, data_write_dtype=_hera_corr_dtype
+    )
+    data_shape = (uvd.Nblts, 1, uvd.Nfreqs, uvd.Npols)
+    data = np.zeros(data_shape, dtype=np.complex64)
+    flags = np.zeros(data_shape, dtype=np.bool)
+    nsamples = np.zeros(data_shape, dtype=np.float32)
+    with h5py.File(filename, 'r+') as h5f:
+        dgrp = h5f['/Data']
+        data_dset = dgrp['visdata']
+        flags_dset = dgrp['flags']
+        nsample_dset = dgrp['nsamples']
+        with data_dset.astype(_hera_corr_dtype):
+            data_dset[:, :, :, :, 'r'] = data.real
+            data_dset[:, :, :, :, 'i'] = data.imag
+        flags_dset = flags
+        nsample_dset = nsamples
+    return
+
+
+def test_read_miriad_write_uvh5_read_uvh5(uv_miriad):
+    """
+    Test a miriad file round trip.
+    """
+    uv_in = uv_miriad
     uv_out = UVData()
-    miriad_file = os.path.join(DATA_PATH, 'zen.2456865.60537.xy.uvcRREAA')
     testfile = os.path.join(DATA_PATH, 'test', 'outtest_miriad.uvh5')
-    uvtest.checkWarnings(uv_in.read_miriad, [miriad_file],
-                         nwarnings=1, category=[UserWarning],
-                         message=['Altitude is not present'])
     uv_in.write_uvh5(testfile, clobber=True)
     uv_out.read(testfile)
     assert uv_in == uv_out
@@ -50,23 +168,21 @@ def test_ReadMiriadWriteUVH5ReadUVH5():
     return
 
 
-def test_ReadUVFITSWriteUVH5ReadUVH5():
+def test_read_uvfits_write_uvh5_read_uvh5(uv_uvfits):
     """
-    UVFITS round trip test
+    Test a uvfits file round trip.
     """
-    uv_in = UVData()
+    uv_in = uv_uvfits
     uv_out = UVData()
-    uvfits_file = os.path.join(DATA_PATH, 'day2_TDEM0003_10s_norx_1src_1spw.uvfits')
     testfile = os.path.join(DATA_PATH, 'test', 'outtest_uvfits.uvh5')
-    uvtest.checkWarnings(uv_in.read_uvfits, [uvfits_file], message='Telescope EVLA is not')
     uv_in.write_uvh5(testfile, clobber=True)
-    uvtest.checkWarnings(uv_out.read, [testfile], message='Telescope EVLA is not')
+    uv_out.read(testfile)
     assert uv_in == uv_out
 
     # also test writing double-precision data_array
     uv_in.data_array = uv_in.data_array.astype(np.complex128)
     uv_in.write_uvh5(testfile, clobber=True)
-    uvtest.checkWarnings(uv_out.read, [testfile], message='Telescope EVLA is not')
+    uv_out.read(testfile)
     assert uv_in == uv_out
 
     # clean up
@@ -75,35 +191,37 @@ def test_ReadUVFITSWriteUVH5ReadUVH5():
     return
 
 
-def test_ReadUVH5Errors():
+def test_read_uvh5_errors():
     """
-    Test raising errors in read function
+    Test raising errors in read function.
     """
     uv_in = UVData()
     fake_file = os.path.join(DATA_PATH, 'fake_file.uvh5')
-    pytest.raises(IOError, uv_in.read_uvh5, fake_file)
+    with pytest.raises(IOError) as cm:
+        uv_in.read_uvh5(fake_file)
+    assert str(cm.value).startswith("{} not found".format(fake_file))
 
     return
 
 
-def test_WriteUVH5Errors():
+def test_write_uvh5_errors(uv_uvfits):
     """
-    Test raising errors in write_uvh5 function
+    Test raising errors in write_uvh5 function.
     """
-    uv_in = UVData()
+    uv_in = uv_uvfits
     uv_out = UVData()
-    uvfits_file = os.path.join(DATA_PATH, 'day2_TDEM0003_10s_norx_1src_1spw.uvfits')
-    uvtest.checkWarnings(uv_in.read_uvfits, [uvfits_file], message='Telescope EVLA is not')
     testfile = os.path.join(DATA_PATH, 'test', 'outtest_uvfits.uvh5')
     with open(testfile, 'a'):
         os.utime(testfile, None)
 
     # assert IOError if file exists
-    pytest.raises(IOError, uv_in.write_uvh5, testfile, clobber=False)
+    with pytest.raises(IOError) as cm:
+        uv_in.write_uvh5(testfile, clobber=False)
+    assert str(cm.value).startswith("File exists; skipping")
 
     # use clobber=True to write out anyway
     uv_in.write_uvh5(testfile, clobber=True)
-    uvtest.checkWarnings(uv_out.read, [testfile], message='Telescope EVLA is not')
+    uv_out.read(testfile)
     assert uv_in == uv_out
 
     # clean up
@@ -112,14 +230,12 @@ def test_WriteUVH5Errors():
     return
 
 
-def test_UVH5OptionalParameters():
+def test_uvh5_optional_parameters(uv_uvfits):
     """
-    Test reading and writing optional parameters not in sample files
+    Test reading and writing optional parameters not in sample files.
     """
-    uv_in = UVData()
+    uv_in = uv_uvfits
     uv_out = UVData()
-    uvfits_file = os.path.join(DATA_PATH, 'day2_TDEM0003_10s_norx_1src_1spw.uvfits')
-    uvtest.checkWarnings(uv_in.read_uvfits, [uvfits_file], message='Telescope EVLA is not')
     testfile = os.path.join(DATA_PATH, 'test', 'outtest_uvfits.uvh5')
 
     # set optional parameters
@@ -132,14 +248,14 @@ def test_UVH5OptionalParameters():
 
     # write out and read back in
     uv_in.write_uvh5(testfile, clobber=True)
-    uvtest.checkWarnings(uv_out.read, [testfile], message='Telescope EVLA is not')
+    uv_out.read(testfile)
     assert uv_in == uv_out
 
     # test with blt_order = bda as well (single entry in tuple)
     uv_in.reorder_blts(order='bda')
 
     uv_in.write_uvh5(testfile, clobber=True)
-    uvtest.checkWarnings(uv_out.read, [testfile], message='Telescope EVLA is not')
+    uv_out.read(testfile)
     assert uv_in == uv_out
 
     # clean up
@@ -148,20 +264,23 @@ def test_UVH5OptionalParameters():
     return
 
 
-def test_UVH5CompressionOptions():
+def test_uvh5_compression_options(uv_uvfits):
     """
-    Test writing data with compression filters
+    Test writing data with compression filters.
     """
-    uv_in = UVData()
+    uv_in = uv_uvfits
     uv_out = UVData()
-    uvfits_file = os.path.join(DATA_PATH, 'day2_TDEM0003_10s_norx_1src_1spw.uvfits')
-    uvtest.checkWarnings(uv_in.read_uvfits, [uvfits_file], message='Telescope EVLA is not')
     testfile = os.path.join(DATA_PATH, 'test', 'outtest_uvfits_compression.uvh5')
 
     # write out and read back in
-    uv_in.write_uvh5(testfile, clobber=True, data_compression="lzf",
-                     flags_compression=None, nsample_compression=None)
-    uvtest.checkWarnings(uv_out.read, [testfile], message='Telescope EVLA is not')
+    uv_in.write_uvh5(
+        testfile,
+        clobber=True,
+        data_compression="lzf",
+        flags_compression=None,
+        nsample_compression=None
+    )
+    uv_out.read(testfile)
     assert uv_in == uv_out
 
     # clean up
@@ -170,30 +289,27 @@ def test_UVH5CompressionOptions():
     return
 
 
-def test_UVH5ReadMultiple_files():
+def test_uvh5_read_multiple_files(uv_uvfits):
     """
-    Test reading multiple uvh5 files
+    Test reading multiple uvh5 files.
     """
-    uv_full = UVData()
-    uvfits_file = os.path.join(DATA_PATH, 'day2_TDEM0003_10s_norx_1src_1spw.uvfits')
+    uv_in = uv_uvfits
     testfile1 = os.path.join(DATA_PATH, 'test/uv1.uvh5')
     testfile2 = os.path.join(DATA_PATH, 'test/uv2.uvh5')
-    uvtest.checkWarnings(uv_full.read_uvfits, [uvfits_file], message='Telescope EVLA is not')
-    uv1 = copy.deepcopy(uv_full)
-    uv2 = copy.deepcopy(uv_full)
+    uv1 = uv_in.copy()
+    uv2 = uv_in.copy()
     uv1.select(freq_chans=np.arange(0, 32))
     uv2.select(freq_chans=np.arange(32, 64))
     uv1.write_uvh5(testfile1, clobber=True)
     uv2.write_uvh5(testfile2, clobber=True)
-    uvtest.checkWarnings(uv1.read, [[testfile1, testfile2]], nwarnings=2,
-                         message='Telescope EVLA is not')
+    uv1.read([testfile1, testfile2])
     # Check history is correct, before replacing and doing a full object check
-    assert uvutils._check_histories(uv_full.history + '  Downselected to '
+    assert uvutils._check_histories(uv_in.history + '  Downselected to '
                                     'specific frequencies using pyuvdata. '
                                     'Combined data along frequency axis using'
                                     ' pyuvdata.', uv1.history)
-    uv1.history = uv_full.history
-    assert uv1 == uv_full
+    uv1.history = uv_in.history
+    assert uv1 == uv_in
 
     # clean up
     os.remove(testfile1)
@@ -202,27 +318,24 @@ def test_UVH5ReadMultiple_files():
     return
 
 
-def test_UVH5ReadMultiple_files_metadata_only():
+def test_uvh5_read_multiple_files_metadata_only(uv_uvfits):
     """
-    Test reading multiple uvh5 files with metadata only
+    Test reading multiple uvh5 files with metadata only.
     """
-    uv_full = UVData()
-    uvfits_file = os.path.join(DATA_PATH, 'day2_TDEM0003_10s_norx_1src_1spw.uvfits')
+    uv_in = uv_uvfits
     testfile1 = os.path.join(DATA_PATH, 'test/uv1.uvh5')
     testfile2 = os.path.join(DATA_PATH, 'test/uv2.uvh5')
-    uvtest.checkWarnings(uv_full.read_uvfits, [uvfits_file], message='Telescope EVLA is not')
-    uv1 = copy.deepcopy(uv_full)
-    uv2 = copy.deepcopy(uv_full)
+    uv1 = uv_in.copy()
+    uv2 = uv_in.copy()
     uv1.select(freq_chans=np.arange(0, 32))
     uv2.select(freq_chans=np.arange(32, 64))
     uv1.write_uvh5(testfile1, clobber=True)
     uv2.write_uvh5(testfile2, clobber=True)
 
+    uvfits_filename = os.path.join(DATA_PATH, "day2_TDEM0003_10s_norx_1src_1spw.uvfits")
     uv_full = UVData()
-    uvtest.checkWarnings(uv_full.read_uvfits, [uvfits_file], {'read_data': False},
-                         message='Telescope EVLA is not')
-    uvtest.checkWarnings(uv1.read, [[testfile1, testfile2]], {'read_data': False},
-                         nwarnings=2, message='Telescope EVLA is not')
+    uv_full.read_uvfits(uvfits_filename, read_data=False)
+    uv1.read([testfile1, testfile2], read_data=False)
     # Check history is correct, before replacing and doing a full object check
     assert uvutils._check_histories(uv_full.history + '  Downselected to '
                                     'specific frequencies using pyuvdata. '
@@ -238,30 +351,27 @@ def test_UVH5ReadMultiple_files_metadata_only():
     return
 
 
-def test_UVH5ReadMultiple_files_axis():
+def test_uvh5_rea_multiple_files_axis(uv_uvfits):
     """
-    Test reading multiple uvh5 files with setting axis
+    Test reading multiple uvh5 files with setting axis.
     """
-    uv_full = UVData()
-    uvfits_file = os.path.join(DATA_PATH, 'day2_TDEM0003_10s_norx_1src_1spw.uvfits')
+    uv_in = uv_uvfits
     testfile1 = os.path.join(DATA_PATH, 'test/uv1.uvh5')
     testfile2 = os.path.join(DATA_PATH, 'test/uv2.uvh5')
-    uvtest.checkWarnings(uv_full.read_uvfits, [uvfits_file], message='Telescope EVLA is not')
-    uv1 = copy.deepcopy(uv_full)
-    uv2 = copy.deepcopy(uv_full)
+    uv1 = uv_in.copy()
+    uv2 = uv_in.copy()
     uv1.select(freq_chans=np.arange(0, 32))
     uv2.select(freq_chans=np.arange(32, 64))
     uv1.write_uvh5(testfile1, clobber=True)
     uv2.write_uvh5(testfile2, clobber=True)
-    uvtest.checkWarnings(uv1.read, [[testfile1, testfile2]], {'axis': 'freq'},
-                         nwarnings=2, message='Telescope EVLA is not')
+    uv1.read([testfile1, testfile2], axis="freq")
     # Check history is correct, before replacing and doing a full object check
-    assert uvutils._check_histories(uv_full.history + '  Downselected to '
+    assert uvutils._check_histories(uv_in.history + '  Downselected to '
                                     'specific frequencies using pyuvdata. '
                                     'Combined data along frequency axis using'
                                     ' pyuvdata.', uv1.history)
-    uv1.history = uv_full.history
-    assert uv1 == uv_full
+    uv1.history = uv_in.history
+    assert uv1 == uv_in
 
     # clean up
     os.remove(testfile1)
@@ -270,17 +380,18 @@ def test_UVH5ReadMultiple_files_axis():
     return
 
 
-def test_UVH5PartialRead():
+def test_uvh5_partial_read_antennas(uv_uvfits):
     """
-    Test reading in only part of a dataset from disk
+    Test reading in only certain antennas from disk.
     """
+    uv_in = uv_uvfits
     uvh5_uv = UVData()
     uvh5_uv2 = UVData()
-    uvfits_file = os.path.join(DATA_PATH, 'day2_TDEM0003_10s_norx_1src_1spw.uvfits')
-    uvtest.checkWarnings(uvh5_uv.read_uvfits, [uvfits_file], message='Telescope EVLA is not')
     testfile = os.path.join(DATA_PATH, 'test', 'outtest.uvh5')
-    uvh5_uv.telescope_name = 'PAPER'
-    uvh5_uv.write_uvh5(testfile, clobber=True)
+    # change telescope name to avoid errors
+    uv_in.telescope_name = "PAPER"
+    uv_in.write_uvh5(testfile, clobber=True)
+    uvh5_uv.read(testfile)
 
     # select on antennas
     ants_to_keep = np.array([0, 19, 11, 24, 3, 23, 1, 20, 21])
@@ -289,6 +400,25 @@ def test_UVH5PartialRead():
     uvh5_uv2.select(antenna_nums=ants_to_keep)
     assert uvh5_uv == uvh5_uv2
 
+    # clean up
+    os.remove(testfile)
+
+    return
+
+
+def test_uvh5_partial_read_freqs(uv_uvfits):
+    """
+    Test reading in only certain frequencies from disk.
+    """
+    uv_in = uv_uvfits
+    uvh5_uv = UVData()
+    uvh5_uv2 = UVData()
+    testfile = os.path.join(DATA_PATH, 'test', 'outtest.uvh5')
+    # change telescope name to avoid errors
+    uv_in.telescope_name = "PAPER"
+    uv_in.write_uvh5(testfile, clobber=True)
+    uvh5_uv.read(testfile)
+
     # select on frequency channels
     chans_to_keep = np.arange(12, 22)
     uvh5_uv.read(testfile, freq_chans=chans_to_keep)
@@ -296,6 +426,25 @@ def test_UVH5PartialRead():
     uvh5_uv2.select(freq_chans=chans_to_keep)
     assert uvh5_uv == uvh5_uv2
 
+    # clean up
+    os.remove(testfile)
+
+    return
+
+
+def test_uvh5_partial_read_pols(uv_uvfits):
+    """
+    Test reading in only certain polarizations from disk.
+    """
+    uv_in = uv_uvfits
+    uvh5_uv = UVData()
+    uvh5_uv2 = UVData()
+    testfile = os.path.join(DATA_PATH, 'test', 'outtest.uvh5')
+    # change telescope name to avoid errors
+    uv_in.telescope_name = "PAPER"
+    uv_in.write_uvh5(testfile, clobber=True)
+    uvh5_uv.read(testfile)
+
     # select on pols
     pols_to_keep = [-1, -2]
     uvh5_uv.read(testfile, polarizations=pols_to_keep)
@@ -303,17 +452,58 @@ def test_UVH5PartialRead():
     uvh5_uv2.select(polarizations=pols_to_keep)
     assert uvh5_uv == uvh5_uv2
 
+    return
+
+
+def test_uvh5_partial_read_times(uv_uvfits):
+    """
+    Test reading in only certain times from disk.
+    """
+    uv_in = uv_uvfits
+    uvh5_uv = UVData()
+    uvh5_uv2 = UVData()
+    testfile = os.path.join(DATA_PATH, 'test', 'outtest.uvh5')
+    # change telescope name to avoid errors
+    uv_in.telescope_name = "PAPER"
+    uv_in.write_uvh5(testfile, clobber=True)
+    uvh5_uv.read(testfile)
+
     # select on read using time_range
     unique_times = np.unique(uvh5_uv.time_array)
-    uvtest.checkWarnings(uvh5_uv.read, [testfile],
-                         {'time_range': [unique_times[0], unique_times[1]]},
-                         message=['Warning: "time_range" keyword is set'])
+    uvtest.checkWarnings(
+        uvh5_uv.read,
+        [testfile],
+        {'time_range': [unique_times[0], unique_times[1]]},
+        message=['Warning: "time_range" keyword is set']
+    )
     uvh5_uv2.read(testfile)
     uvh5_uv2.select(times=unique_times[0:2])
     assert uvh5_uv == uvh5_uv2
 
+    # clean up
+    os.remove(testfile)
+
+    return
+
+
+def test_uvh5_partial_read_multi1(uv_uvfits):
+    """
+    Test select-on-read for multiple axes, frequencies being smallest fraction.
+    """
+    uv_in = uv_uvfits
+    uvh5_uv = UVData()
+    uvh5_uv2 = UVData()
+    testfile = os.path.join(DATA_PATH, 'test', 'outtest.uvh5')
+    # change telescope name to avoid errors
+    uv_in.telescope_name = "PAPER"
+    uv_in.write_uvh5(testfile, clobber=True)
+    uvh5_uv.read(testfile)
+
     # now test selecting on multiple axes
-    # frequencies first
+    # read frequencies first
+    ants_to_keep = np.array([0, 19, 11, 24, 3, 23, 1, 20, 21])
+    chans_to_keep = np.arange(12, 22)
+    pols_to_keep = [-1, -2]
     uvh5_uv.read(testfile, antenna_nums=ants_to_keep, freq_chans=chans_to_keep,
                  polarizations=pols_to_keep)
     uvh5_uv2.read(testfile)
@@ -321,8 +511,30 @@ def test_UVH5PartialRead():
                     polarizations=pols_to_keep)
     assert uvh5_uv == uvh5_uv2
 
-    # baselines first
+    # clean up
+    os.remove(testfile)
+
+    return
+
+
+def test_uvh5_partial_read_multi2(uv_uvfits):
+    """
+    Test select-on-read for multiple axes, baselines being smallest fraction.
+    """
+    uv_in = uv_uvfits
+    uvh5_uv = UVData()
+    uvh5_uv2 = UVData()
+    testfile = os.path.join(DATA_PATH, 'test', 'outtest.uvh5')
+    # change telescope name to avoid errors
+    uv_in.telescope_name = "PAPER"
+    uv_in.write_uvh5(testfile, clobber=True)
+    uvh5_uv.read(testfile)
+
+    # now test selecting on multiple axes
+    # read baselines first
     ants_to_keep = np.array([0, 1])
+    chans_to_keep = np.arange(12, 22)
+    pols_to_keep = [-1, -2]
     uvh5_uv.read(testfile, antenna_nums=ants_to_keep, freq_chans=chans_to_keep,
                  polarizations=pols_to_keep)
     uvh5_uv2.read(testfile)
@@ -330,14 +542,40 @@ def test_UVH5PartialRead():
                     polarizations=pols_to_keep)
     assert uvh5_uv == uvh5_uv2
 
-    # polarizations first
+    # clean up
+    os.remove(testfile)
+
+    return
+
+
+def test_uvh5_partial_read_multi3(uv_uvfits):
+    """
+    Test select-on-read for multiple axes, polarizations being smallest fraction.
+    """
+    uv_in = uv_uvfits
+    uvh5_uv = UVData()
+    uvh5_uv2 = UVData()
+    testfile = os.path.join(DATA_PATH, 'test', 'outtest.uvh5')
+    # change telescope name to avoid errors
+    uv_in.telescope_name = "PAPER"
+    uv_in.write_uvh5(testfile, clobber=True)
+    uvh5_uv.read(testfile)
+
+    # now test selecting on multiple axes
+    # read polarizations first
     ants_to_keep = np.array([0, 1, 2, 3, 6, 7, 8, 11, 14, 18, 19, 20, 21, 22])
     chans_to_keep = np.arange(12, 64)
-    uvh5_uv.read(testfile, antenna_nums=ants_to_keep, freq_chans=chans_to_keep,
-                 polarizations=pols_to_keep)
+    pols_to_keep = [-1, -2]
+    uvh5_uv.read(
+        testfile,
+        antenna_nums=ants_to_keep,
+        freq_chans=chans_to_keep,
+        polarizations=pols_to_keep,
+    )
     uvh5_uv2.read(testfile)
-    uvh5_uv2.select(antenna_nums=ants_to_keep, freq_chans=chans_to_keep,
-                    polarizations=pols_to_keep)
+    uvh5_uv2.select(
+        antenna_nums=ants_to_keep, freq_chans=chans_to_keep, polarizations=pols_to_keep
+    )
     assert uvh5_uv == uvh5_uv2
 
     # clean up
@@ -346,25 +584,15 @@ def test_UVH5PartialRead():
     return
 
 
-def test_UVH5PartialWrite():
+def test_uvh5_partial_write_antpairs(uv_partial_write):
     """
-    Test writing an entire UVH5 file in pieces
+    Test writing an entire UVH5 file in pieces by antpairs.
     """
-    full_uvh5 = UVData()
+    full_uvh5 = uv_partial_write
     partial_uvh5 = UVData()
-    uvfits_file = os.path.join(DATA_PATH, 'day2_TDEM0003_10s_norx_1src_1spw.uvfits')
-    uvtest.checkWarnings(full_uvh5.read_uvfits, [uvfits_file], message='Telescope EVLA is not')
-    testfile = os.path.join(DATA_PATH, 'test', 'outtest.uvh5')
-    full_uvh5.telescope_name = "PAPER"
-    # cut down the file size to decrease testing time
-    full_uvh5.select(antenna_nums=[3, 7, 24])
-    full_uvh5.lst_array = uvutils.get_lst_for_time(full_uvh5.time_array,
-                                                   *full_uvh5.telescope_location_lat_lon_alt_degrees)
-    full_uvh5.write_uvh5(testfile, clobber=True)
-    full_uvh5.read(testfile)
 
     # delete data arrays in partial file
-    partial_uvh5 = copy.deepcopy(full_uvh5)
+    partial_uvh5 = full_uvh5.copy()
     partial_uvh5.data_array = None
     partial_uvh5.flag_array = None
     partial_uvh5.nsample_array = None
@@ -379,8 +607,9 @@ def test_UVH5PartialWrite():
         data = full_uvh5.get_data(key, squeeze='none')
         flags = full_uvh5.get_flags(key, squeeze='none')
         nsamples = full_uvh5.get_nsamples(key, squeeze='none')
-        partial_uvh5.write_uvh5_part(partial_testfile, data, flags, nsamples,
-                                     bls=key)
+        partial_uvh5.write_uvh5_part(
+            partial_testfile, data, flags, nsamples, bls=key
+        )
 
     # now read in the full file and make sure that it matches the original
     partial_uvh5.read(partial_testfile)
@@ -391,19 +620,35 @@ def test_UVH5PartialWrite():
     data = full_uvh5.get_data(key, squeeze='none')
     flags = full_uvh5.get_flags(key, squeeze='none')
     nsamples = full_uvh5.get_nsamples(key, squeeze='none')
-    partial_uvh5.write_uvh5_part(partial_testfile, data, flags, nsamples,
-                                 bls=key, add_to_history="foo")
+    partial_uvh5.write_uvh5_part(
+        partial_testfile, data, flags, nsamples, bls=key, add_to_history="foo"
+    )
     partial_uvh5.read(partial_testfile, read_data=False)
     assert 'foo' in partial_uvh5.history
 
+    # clean up
+    os.remove(partial_testfile)
+
+    return
+
+
+def test_uvh5_partial_write_frequencies(uv_partial_write):
+    """
+    Test writing an entire UVH5 file in pieces by frequencies.
+    """
+    full_uvh5 = uv_partial_write
+    partial_uvh5 = UVData()
+
     # start over, and write frequencies
-    partial_uvh5 = copy.deepcopy(full_uvh5)
+    partial_uvh5 = full_uvh5.copy()
     partial_uvh5.data_array = None
     partial_uvh5.flag_array = None
     partial_uvh5.nsample_array = None
 
     # initialize file on disk
+    partial_testfile = os.path.join(DATA_PATH, 'test', 'outtest_partial.uvh5')
     partial_uvh5.initialize_uvh5_file(partial_testfile, clobber=True)
+
     Nfreqs = full_uvh5.Nfreqs
     Hfreqs = Nfreqs // 2
     freqs1 = np.arange(Hfreqs)
@@ -411,26 +656,43 @@ def test_UVH5PartialWrite():
     data = full_uvh5.data_array[:, :, freqs1, :]
     flags = full_uvh5.flag_array[:, :, freqs1, :]
     nsamples = full_uvh5.nsample_array[:, :, freqs1, :]
-    partial_uvh5.write_uvh5_part(partial_testfile, data, flags, nsamples,
-                                 freq_chans=freqs1)
+    partial_uvh5.write_uvh5_part(
+        partial_testfile, data, flags, nsamples, freq_chans=freqs1
+    )
     data = full_uvh5.data_array[:, :, freqs2, :]
     flags = full_uvh5.flag_array[:, :, freqs2, :]
     nsamples = full_uvh5.nsample_array[:, :, freqs2, :]
-    partial_uvh5.write_uvh5_part(partial_testfile, data, flags, nsamples,
-                                 freq_chans=freqs2)
+    partial_uvh5.write_uvh5_part(
+        partial_testfile, data, flags, nsamples, freq_chans=freqs2
+    )
 
     # read in the full file and make sure it matches
     partial_uvh5.read(partial_testfile)
     assert full_uvh5 == partial_uvh5
 
+    # clean up
+    os.remove(partial_testfile)
+
+    return
+
+
+def test_uvh5_partial_write_blts(uv_partial_write):
+    """
+    Test writing an entire UVH5 file in pieces by blt.
+    """
+    full_uvh5 = uv_partial_write
+    partial_uvh5 = UVData()
+
     # start over, write chunks of blts
-    partial_uvh5 = copy.deepcopy(full_uvh5)
+    partial_uvh5 = full_uvh5.copy()
     partial_uvh5.data_array = None
     partial_uvh5.flag_array = None
     partial_uvh5.nsample_array = None
 
     # initialize file on disk
+    partial_testfile = os.path.join(DATA_PATH, 'test', 'outtest_partial.uvh5')
     partial_uvh5.initialize_uvh5_file(partial_testfile, clobber=True)
+
     Nblts = full_uvh5.Nblts
     Hblts = Nblts // 2
     blts1 = np.arange(Hblts)
@@ -438,26 +700,43 @@ def test_UVH5PartialWrite():
     data = full_uvh5.data_array[blts1, :, :, :]
     flags = full_uvh5.flag_array[blts1, :, :, :]
     nsamples = full_uvh5.nsample_array[blts1, :, :, :]
-    partial_uvh5.write_uvh5_part(partial_testfile, data, flags, nsamples,
-                                 blt_inds=blts1)
+    partial_uvh5.write_uvh5_part(
+        partial_testfile, data, flags, nsamples, blt_inds=blts1
+    )
     data = full_uvh5.data_array[blts2, :, :, :]
     flags = full_uvh5.flag_array[blts2, :, :, :]
     nsamples = full_uvh5.nsample_array[blts2, :, :, :]
-    partial_uvh5.write_uvh5_part(partial_testfile, data, flags, nsamples,
-                                 blt_inds=blts2)
+    partial_uvh5.write_uvh5_part(
+        partial_testfile, data, flags, nsamples, blt_inds=blts2
+    )
 
     # read in the full file and make sure it matches
     partial_uvh5.read(partial_testfile)
-    assert full_uvh5, partial_uvh5
+    assert full_uvh5 == partial_uvh5
+
+    # clean up
+    os.remove(partial_testfile)
+
+    return
+
+
+def test_uvh5_partial_write_pols(uv_partial_write):
+    """
+    Test writing an entire UVH5 file in pieces by pol.
+    """
+    full_uvh5 = uv_partial_write
+    partial_uvh5 = UVData()
 
     # start over, write groups of pols
-    partial_uvh5 = copy.deepcopy(full_uvh5)
+    partial_uvh5 = full_uvh5.copy()
     partial_uvh5.data_array = None
     partial_uvh5.flag_array = None
     partial_uvh5.nsample_array = None
 
     # initialize file on disk
+    partial_testfile = os.path.join(DATA_PATH, 'test', 'outtest_partial.uvh5')
     partial_uvh5.initialize_uvh5_file(partial_testfile, clobber=True)
+
     Npols = full_uvh5.Npols
     Hpols = Npols // 2
     pols1 = np.arange(Hpols)
@@ -465,59 +744,43 @@ def test_UVH5PartialWrite():
     data = full_uvh5.data_array[:, :, :, pols1]
     flags = full_uvh5.flag_array[:, :, :, pols1]
     nsamples = full_uvh5.nsample_array[:, :, :, pols1]
-    partial_uvh5.write_uvh5_part(partial_testfile, data, flags, nsamples,
-                                 polarizations=full_uvh5.polarization_array[:Hpols])
+    partial_uvh5.write_uvh5_part(
+        partial_testfile,
+        data,
+        flags,
+        nsamples,
+        polarizations=full_uvh5.polarization_array[:Hpols]
+    )
     data = full_uvh5.data_array[:, :, :, pols2]
     flags = full_uvh5.flag_array[:, :, :, pols2]
     nsamples = full_uvh5.nsample_array[:, :, :, pols2]
-    partial_uvh5.write_uvh5_part(partial_testfile, data, flags, nsamples,
-                                 polarizations=full_uvh5.polarization_array[Hpols:])
+    partial_uvh5.write_uvh5_part(
+        partial_testfile,
+        data,
+        flags,
+        nsamples,
+        polarizations=full_uvh5.polarization_array[Hpols:]
+    )
 
     # read in the full file and make sure it matches
     partial_uvh5.read(partial_testfile)
     assert full_uvh5 == partial_uvh5
 
     # clean up
-    os.remove(testfile)
     os.remove(partial_testfile)
 
     return
 
 
-def test_UVH5PartialWriteIrregular():
+def test_uvh5_partial_write_irregular_blt(uv_partial_write):
     """
-    Test writing a uvh5 file using irregular intervals
+    Test writing a uvh5 file using irregular intervals for single blt.
     """
-    def initialize_with_zeros(uvd, filename):
-        """
-        Initialize a file with all zeros for data arrays
-        """
-        uvd.initialize_uvh5_file(filename, clobber=True)
-        data_shape = (uvd.Nblts, 1, uvd.Nfreqs, uvd.Npols)
-        data = np.zeros(data_shape, dtype=np.complex64)
-        flags = np.zeros(data_shape, dtype=np.bool)
-        nsamples = np.zeros(data_shape, dtype=np.float32)
-        with h5py.File(filename, 'r+') as f:
-            dgrp = f['/Data']
-            data_dset = dgrp['visdata']
-            flags_dset = dgrp['flags']
-            nsample_dset = dgrp['nsamples']
-            data_dset = data
-            flags_dset = flags
-            nsample_dset = nsamples
-        return
-
-    full_uvh5 = UVData()
+    full_uvh5 = uv_partial_write
     partial_uvh5 = UVData()
-    uvfits_file = os.path.join(DATA_PATH, 'day2_TDEM0003_10s_norx_1src_1spw.uvfits')
-    uvtest.checkWarnings(full_uvh5.read_uvfits, [uvfits_file], message='Telescope EVLA is not')
-    testfile = os.path.join(DATA_PATH, 'test', 'outtest.uvh5')
-    full_uvh5.telescope_name = "PAPER"
-    full_uvh5.write_uvh5(testfile, clobber=True)
-    full_uvh5.read(testfile)
 
     # delete data arrays in partial file
-    partial_uvh5 = copy.deepcopy(full_uvh5)
+    partial_uvh5 = full_uvh5.copy()
     partial_uvh5.data_array = None
     partial_uvh5.flag_array = None
     partial_uvh5.nsample_array = None
@@ -548,9 +811,21 @@ def test_UVH5PartialWriteIrregular():
     partial_uvh5_file.read(partial_testfile)
     assert partial_uvh5_file == partial_uvh5
 
-    # do it again, with a single frequency
-    # reinitialize
-    partial_uvh5 = copy.deepcopy(full_uvh5)
+    # clean up
+    os.remove(partial_testfile)
+
+    return
+
+
+def test_uvh5_partial_write_irregular_freq(uv_partial_write):
+    """
+    Test writing a uvh5 file using irregular intervals for single frequency.
+    """
+    full_uvh5 = uv_partial_write
+    partial_uvh5 = UVData()
+
+    # delete data arrays in partial file
+    partial_uvh5 = full_uvh5.copy()
     partial_uvh5.data_array = None
     partial_uvh5.flag_array = None
     partial_uvh5.nsample_array = None
@@ -569,8 +844,9 @@ def test_UVH5PartialWriteIrregular():
     data = full_uvh5.data_array[:, :, freq_inds, :]
     flags = full_uvh5.flag_array[:, :, freq_inds, :]
     nsamples = full_uvh5.nsample_array[:, :, freq_inds, :]
-    partial_uvh5.write_uvh5_part(partial_testfile, data, flags, nsamples,
-                                 freq_chans=freq_inds)
+    partial_uvh5.write_uvh5_part(
+        partial_testfile, data, flags, nsamples, freq_chans=freq_inds
+    )
 
     # also write the arrays to the partial object
     partial_uvh5.data_array[:, :, freq_inds, :] = data
@@ -582,9 +858,21 @@ def test_UVH5PartialWriteIrregular():
     partial_uvh5_file.read(partial_testfile)
     assert partial_uvh5_file == partial_uvh5
 
-    # do it again, with a single polarization
-    # reinitialize
-    partial_uvh5 = copy.deepcopy(full_uvh5)
+    # clean up
+    os.remove(partial_testfile)
+
+    return
+
+
+def test_uvh5_partial_write_irregular_pol(uv_partial_write):
+    """
+    Test writing a uvh5 file using irregular intervals for single polarization.
+    """
+    full_uvh5 = uv_partial_write
+    partial_uvh5 = UVData()
+
+    # delete data arrays in partial file
+    partial_uvh5 = full_uvh5.copy()
     partial_uvh5.data_array = None
     partial_uvh5.flag_array = None
     partial_uvh5.nsample_array = None
@@ -603,8 +891,13 @@ def test_UVH5PartialWriteIrregular():
     data = full_uvh5.data_array[:, :, :, pol_inds]
     flags = full_uvh5.flag_array[:, :, :, pol_inds]
     nsamples = full_uvh5.nsample_array[:, :, :, pol_inds]
-    partial_uvh5.write_uvh5_part(partial_testfile, data, flags, nsamples,
-                                 polarizations=partial_uvh5.polarization_array[pol_inds])
+    partial_uvh5.write_uvh5_part(
+        partial_testfile,
+        data,
+        flags,
+        nsamples,
+        polarizations=partial_uvh5.polarization_array[pol_inds],
+    )
 
     # also write the arrays to the partial object
     partial_uvh5.data_array[:, :, :, pol_inds] = data
@@ -616,9 +909,22 @@ def test_UVH5PartialWriteIrregular():
     partial_uvh5_file.read(partial_testfile)
     assert partial_uvh5_file == partial_uvh5
 
-    # test irregularly spaced blts and freqs
-    # reinitialize
-    partial_uvh5 = copy.deepcopy(full_uvh5)
+    # clean up
+    os.remove(partial_testfile)
+
+    return
+
+
+def test_uvh5_partial_write_irregular_multi1(uv_partial_write):
+    """
+    Test writing a uvh5 file using irregular intervals for blts and freqs.
+    """
+    full_uvh5 = uv_partial_write
+    full_uvh5.telescope_name = "PAPER"
+    partial_uvh5 = UVData()
+
+    # delete data arrays in partial file
+    partial_uvh5 = full_uvh5.copy()
     partial_uvh5.data_array = None
     partial_uvh5.flag_array = None
     partial_uvh5.nsample_array = None
@@ -644,9 +950,12 @@ def test_UVH5PartialWriteIrregular():
             data[iblt, :, ifreq, :] = full_uvh5.data_array[blt_idx, :, freq_idx, :]
             flags[iblt, :, ifreq, :] = full_uvh5.flag_array[blt_idx, :, freq_idx, :]
             nsamples[iblt, :, ifreq, :] = full_uvh5.nsample_array[blt_idx, :, freq_idx, :]
-    uvtest.checkWarnings(partial_uvh5.write_uvh5_part, [partial_testfile, data, flags, nsamples],
-                         {'blt_inds': blt_inds, 'freq_chans': freq_inds},
-                         message='Selected frequencies are not evenly spaced')
+    uvtest.checkWarnings(
+        partial_uvh5.write_uvh5_part,
+        [partial_testfile, data, flags, nsamples],
+        {'blt_inds': blt_inds, 'freq_chans': freq_inds},
+        message='Selected frequencies are not evenly spaced',
+    )
 
     # also write the arrays to the partial object
     for iblt, blt_idx in enumerate(blt_inds):
@@ -660,9 +969,22 @@ def test_UVH5PartialWriteIrregular():
     partial_uvh5_file.read(partial_testfile)
     assert partial_uvh5_file == partial_uvh5
 
-    # test irregularly spaced freqs and pols
-    # reinitialize
-    partial_uvh5 = copy.deepcopy(full_uvh5)
+    # clean up
+    os.remove(partial_testfile)
+
+    return
+
+
+def test_uvh5_partial_write_irregular_multi2(uv_partial_write):
+    """
+    Test writing a uvh5 file using irregular intervals for freqs and pols.
+    """
+    full_uvh5 = uv_partial_write
+    full_uvh5.telescope_name = "PAPER"
+    partial_uvh5 = UVData()
+
+    # delete data arrays in partial file
+    partial_uvh5 = full_uvh5.copy()
     partial_uvh5.data_array = None
     partial_uvh5.flag_array = None
     partial_uvh5.nsample_array = None
@@ -676,7 +998,7 @@ def test_UVH5PartialWriteIrregular():
     partial_uvh5.flag_array = np.zeros_like(full_uvh5.flag_array, dtype=np.bool)
     partial_uvh5.nsample_array = np.zeros_like(full_uvh5.nsample_array, dtype=np.float32)
 
-    # define blts and freqs
+    # define freqs and pols
     freq_inds = [0, 1, 2, 7]
     pol_inds = [0, 1, 3]
     data_shape = (full_uvh5.Nblts, 1, len(freq_inds), len(pol_inds))
@@ -688,10 +1010,16 @@ def test_UVH5PartialWriteIrregular():
             data[:, :, ifreq, ipol] = full_uvh5.data_array[:, :, freq_idx, pol_idx]
             flags[:, :, ifreq, ipol] = full_uvh5.flag_array[:, :, freq_idx, pol_idx]
             nsamples[:, :, ifreq, ipol] = full_uvh5.nsample_array[:, :, freq_idx, pol_idx]
-    uvtest.checkWarnings(partial_uvh5.write_uvh5_part, [partial_testfile, data, flags, nsamples],
-                         {'freq_chans': freq_inds, 'polarizations': full_uvh5.polarization_array[pol_inds]},
-                         nwarnings=2, message=['Selected frequencies are not evenly spaced',
-                                               'Selected polarization values are not evenly spaced'])
+    uvtest.checkWarnings(
+        partial_uvh5.write_uvh5_part,
+        [partial_testfile, data, flags, nsamples],
+        {'freq_chans': freq_inds, 'polarizations': full_uvh5.polarization_array[pol_inds]},
+        nwarnings=2,
+        message=[
+            'Selected frequencies are not evenly spaced',
+            'Selected polarization values are not evenly spaced',
+        ]
+    )
 
     # also write the arrays to the partial object
     for ifreq, freq_idx in enumerate(freq_inds):
@@ -705,9 +1033,22 @@ def test_UVH5PartialWriteIrregular():
     partial_uvh5_file.read(partial_testfile)
     assert partial_uvh5_file == partial_uvh5
 
-    # test irregularly spaced blts and pols
-    # reinitialize
-    partial_uvh5 = copy.deepcopy(full_uvh5)
+    # clean up
+    os.remove(partial_testfile)
+
+    return
+
+
+def test_uvh5_partial_write_irregular_multi3(uv_partial_write):
+    """
+    Test writing a uvh5 file using irregular intervals for blts and pols.
+    """
+    full_uvh5 = uv_partial_write
+    full_uvh5.telescope_name = "PAPER"
+    partial_uvh5 = UVData()
+
+    # delete data arrays in partial file
+    partial_uvh5 = full_uvh5.copy()
     partial_uvh5.data_array = None
     partial_uvh5.flag_array = None
     partial_uvh5.nsample_array = None
@@ -733,9 +1074,12 @@ def test_UVH5PartialWriteIrregular():
             data[iblt, :, :, ipol] = full_uvh5.data_array[blt_idx, :, :, pol_idx]
             flags[iblt, :, :, ipol] = full_uvh5.flag_array[blt_idx, :, :, pol_idx]
             nsamples[iblt, :, :, ipol] = full_uvh5.nsample_array[blt_idx, :, :, pol_idx]
-    uvtest.checkWarnings(partial_uvh5.write_uvh5_part, [partial_testfile, data, flags, nsamples],
-                         {'blt_inds': blt_inds, 'polarizations': full_uvh5.polarization_array[pol_inds]},
-                         message='Selected polarization values are not evenly spaced')
+    uvtest.checkWarnings(
+        partial_uvh5.write_uvh5_part,
+        [partial_testfile, data, flags, nsamples],
+        {'blt_inds': blt_inds, 'polarizations': full_uvh5.polarization_array[pol_inds]},
+        message='Selected polarization values are not evenly spaced',
+    )
 
     # also write the arrays to the partial object
     for iblt, blt_idx in enumerate(blt_inds):
@@ -749,54 +1093,19 @@ def test_UVH5PartialWriteIrregular():
     partial_uvh5_file.read(partial_testfile)
     assert partial_uvh5_file == partial_uvh5
 
-    # test irregularly spaced freqs and pols
-    # reinitialize
-    partial_uvh5 = copy.deepcopy(full_uvh5)
-    partial_uvh5.data_array = None
-    partial_uvh5.flag_array = None
-    partial_uvh5.nsample_array = None
-
-    # initialize file on disk
-    partial_testfile = os.path.join(DATA_PATH, 'test', 'outtest_partial.uvh5')
-    initialize_with_zeros(partial_uvh5, partial_testfile)
-
-    # make a mostly empty object in memory to match what we'll write to disk
-    partial_uvh5.data_array = np.zeros_like(full_uvh5.data_array, dtype=np.complex64)
-    partial_uvh5.flag_array = np.zeros_like(full_uvh5.flag_array, dtype=np.bool)
-    partial_uvh5.nsample_array = np.zeros_like(full_uvh5.nsample_array, dtype=np.float32)
-
-    # define blts and freqs
-    freq_inds = [0, 1, 2, 7]
-    pol_inds = [0, 1, 3]
-    data_shape = (full_uvh5.Nblts, 1, len(freq_inds), len(pol_inds))
-    data = np.zeros(data_shape, dtype=np.complex64)
-    flags = np.zeros(data_shape, dtype=np.bool)
-    nsamples = np.zeros(data_shape, dtype=np.float32)
-    for ifreq, freq_idx in enumerate(freq_inds):
-        for ipol, pol_idx in enumerate(pol_inds):
-            data[:, :, ifreq, ipol] = full_uvh5.data_array[:, :, freq_idx, pol_idx]
-            flags[:, :, ifreq, ipol] = full_uvh5.flag_array[:, :, freq_idx, pol_idx]
-            nsamples[:, :, ifreq, ipol] = full_uvh5.nsample_array[:, :, freq_idx, pol_idx]
-    uvtest.checkWarnings(partial_uvh5.write_uvh5_part, [partial_testfile, data, flags, nsamples],
-                         {'freq_chans': freq_inds, 'polarizations': full_uvh5.polarization_array[pol_inds]},
-                         nwarnings=2, message=['Selected frequencies are not evenly spaced',
-                                               'Selected polarization values are not evenly spaced'])
+    return
 
-    # also write the arrays to the partial object
-    for ifreq, freq_idx in enumerate(freq_inds):
-        for ipol, pol_idx in enumerate(pol_inds):
-            partial_uvh5.data_array[:, :, freq_idx, pol_idx] = data[:, :, ifreq, ipol]
-            partial_uvh5.flag_array[:, :, freq_idx, pol_idx] = flags[:, :, ifreq, ipol]
-            partial_uvh5.nsample_array[:, :, freq_idx, pol_idx] = nsamples[:, :, ifreq, ipol]
 
-    # read in the file and make sure it matches
-    partial_uvh5_file = UVData()
-    partial_uvh5_file.read(partial_testfile)
-    assert partial_uvh5_file == partial_uvh5
+def test_uvh5_partial_write_irregular_multi4(uv_partial_write):
+    """
+    Test writing a uvh5 file using irregular intervals for all axes.
+    """
+    full_uvh5 = uv_partial_write
+    full_uvh5.telescope_name = "PAPER"
+    partial_uvh5 = UVData()
 
-    # test irregularly spaced everything
-    # reinitialize
-    partial_uvh5 = copy.deepcopy(full_uvh5)
+    # delete data arrays in partial file
+    partial_uvh5 = full_uvh5.copy()
     partial_uvh5.data_array = None
     partial_uvh5.flag_array = None
     partial_uvh5.nsample_array = None
@@ -824,11 +1133,20 @@ def test_UVH5PartialWriteIrregular():
                 data[iblt, :, ifreq, ipol] = full_uvh5.data_array[blt_idx, :, freq_idx, pol_idx]
                 flags[iblt, :, ifreq, ipol] = full_uvh5.flag_array[blt_idx, :, freq_idx, pol_idx]
                 nsamples[iblt, :, ifreq, ipol] = full_uvh5.nsample_array[blt_idx, :, freq_idx, pol_idx]
-    uvtest.checkWarnings(partial_uvh5.write_uvh5_part, [partial_testfile, data, flags, nsamples],
-                         {'blt_inds': blt_inds, 'freq_chans': freq_inds,
-                          'polarizations': full_uvh5.polarization_array[pol_inds]},
-                         nwarnings=2, message=['Selected frequencies are not evenly spaced',
-                                               'Selected polarization values are not evenly spaced'])
+    uvtest.checkWarnings(
+        partial_uvh5.write_uvh5_part,
+        [partial_testfile, data, flags, nsamples],
+        {
+            'blt_inds': blt_inds,
+            'freq_chans': freq_inds,
+            'polarizations': full_uvh5.polarization_array[pol_inds],
+        },
+        nwarnings=2,
+        message=[
+            'Selected frequencies are not evenly spaced',
+            'Selected polarization values are not evenly spaced',
+        ]
+    )
 
     # also write the arrays to the partial object
     for iblt, blt_idx in enumerate(blt_inds):
@@ -844,24 +1162,17 @@ def test_UVH5PartialWriteIrregular():
     assert partial_uvh5_file == partial_uvh5
 
     # clean up
-    os.remove(testfile)
     os.remove(partial_testfile)
 
     return
 
 
-def test_UVH5PartialWriteErrors():
+def test_uvh5_partial_write_errors(uv_partial_write):
     """
-    Test errors in uvh5_write_part method
+    Test errors in uvh5_write_part method.
     """
-    full_uvh5 = UVData()
+    full_uvh5 = uv_partial_write
     partial_uvh5 = UVData()
-    uvfits_file = os.path.join(DATA_PATH, 'day2_TDEM0003_10s_norx_1src_1spw.uvfits')
-    uvtest.checkWarnings(full_uvh5.read_uvfits, [uvfits_file], message='Telescope EVLA is not')
-    testfile = os.path.join(DATA_PATH, 'test', 'outtest.uvh5')
-    full_uvh5.telescope_name = "PAPER"
-    full_uvh5.write_uvh5(testfile, clobber=True)
-    full_uvh5.read(testfile)
 
     # get a waterfall
     antpairpols = full_uvh5.get_antpairpols()
@@ -871,7 +1182,7 @@ def test_UVH5PartialWriteErrors():
     nsamples = full_uvh5.get_data(key, squeeze='none')
 
     # delete data arrays in partial file
-    partial_uvh5 = copy.deepcopy(full_uvh5)
+    partial_uvh5 = full_uvh5.copy()
     partial_uvh5.data_array = None
     partial_uvh5.flag_array = None
     partial_uvh5.nsample_array = None
@@ -880,95 +1191,148 @@ def test_UVH5PartialWriteErrors():
     partial_testfile = os.path.join(DATA_PATH, 'test', 'outtest_partial.uvh5')
     if os.path.exists(partial_testfile):
         os.remove(partial_testfile)
-    pytest.raises(AssertionError, partial_uvh5.write_uvh5_part, partial_testfile, data,
-                  flags, nsamples, bls=key)
+    with pytest.raises(AssertionError) as cm:
+        partial_uvh5.write_uvh5_part(
+            partial_testfile, data, flags, nsamples, bls=key
+        )
+    assert str(cm.value).startswith("{} does not exist".format(partial_testfile))
 
     # initialize file on disk
     partial_uvh5.initialize_uvh5_file(partial_testfile, clobber=True)
 
     # pass in arrays that are different sizes
-    pytest.raises(AssertionError, partial_uvh5.write_uvh5_part, partial_testfile, data,
-                  flags[:, :, :, 0], nsamples, bls=key)
-    pytest.raises(AssertionError, partial_uvh5.write_uvh5_part, partial_testfile, data,
-                  flags, nsamples[:, :, :, 0], bls=key)
+    with pytest.raises(AssertionError) as cm:
+        partial_uvh5.write_uvh5_part(
+            partial_testfile, data, flags[:, :, :, 0], nsamples, bls=key
+        )
+    assert str(cm.value).startswith("data_array and flag_array must have the same shape")
+    with pytest.raises(AssertionError) as cm:
+        partial_uvh5.write_uvh5_part(
+            partial_testfile, data, flags, nsamples[:, :, :, 0], bls=key
+        )
+    assert str(cm.value).startswith("data_array and nsample_array must have the same shape")
 
     # pass in arrays that are the same size, but don't match expected shape
-    pytest.raises(AssertionError, partial_uvh5.write_uvh5_part, partial_testfile, data[:, :, :, 0],
-                  flags[:, :, :, 0], nsamples[:, :, :, 0])
+    with pytest.raises(AssertionError) as cm:
+        partial_uvh5.write_uvh5_part(
+            partial_testfile, data[:, :, :, 0], flags[:, :, :, 0], nsamples[:, :, :, 0]
+        )
+    assert str(cm.value).startswith("data_array has shape")
 
     # initialize a file on disk, and pass in a different object so check_header fails
     empty_uvd = UVData()
-    pytest.raises(AssertionError, empty_uvd.write_uvh5_part, partial_testfile, data,
-                  flags, nsamples, bls=key)
+    with pytest.raises(AssertionError) as cm:
+        empty_uvd.write_uvh5_part(
+            partial_testfile, data, flags, nsamples, bls=key
+        )
+    assert str(cm.value).startswith(
+        "The object metadata in memory and metadata on disk are different"
+    )
 
     # clean up
-    os.remove(testfile)
     os.remove(partial_testfile)
 
     return
 
 
-def test_UVH5InitializeFile():
+def test_initialize_uvh5_file(uv_partial_write):
     """
-    Test initializing a UVH5 file on disk
+    Test initializing a UVH5 file on disk.
     """
-    full_uvh5 = UVData()
-    partial_uvh5 = UVData()
-    uvfits_file = os.path.join(DATA_PATH, 'day2_TDEM0003_10s_norx_1src_1spw.uvfits')
-    uvtest.checkWarnings(full_uvh5.read_uvfits, [uvfits_file], message='Telescope EVLA is not')
-    testfile = os.path.join(DATA_PATH, 'test', 'outtest.uvh5')
-    full_uvh5.telescope_name = "PAPER"
-    full_uvh5.write_uvh5(testfile, clobber=True)
-    full_uvh5.read(testfile)
+    full_uvh5 = uv_partial_write
     full_uvh5.data_array = None
     full_uvh5.flag_array = None
     full_uvh5.nsample_array = None
 
     # initialize file
-    partial_uvh5 = copy.deepcopy(full_uvh5)
+    partial_uvh5 = full_uvh5.copy()
     partial_testfile = os.path.join(DATA_PATH, 'test', 'outtest_partial.uvh5')
     partial_uvh5.initialize_uvh5_file(partial_testfile, clobber=True)
 
-    # read it in and make sure that the metadata matches the original
-    partial_uvh5.read(partial_testfile, read_data=False)
-    assert partial_uvh5 == full_uvh5
+    # read it in and make sure that the metadata matches the original
+    partial_uvh5.read(partial_testfile, read_data=False)
+    assert partial_uvh5 == full_uvh5
+
+    # clean up
+    os.remove(partial_testfile)
+
+    return
+
+
+def test_initialize_uvh5_file_errors(uv_partial_write):
+    """
+    Test errors in initializing a UVH5 file on disk.
+    """
+    full_uvh5 = uv_partial_write
+    full_uvh5.data_array = None
+    full_uvh5.flag_array = None
+    full_uvh5.nsample_array = None
+
+    # initialize file
+    partial_uvh5 = full_uvh5.copy()
+    partial_testfile = os.path.join(DATA_PATH, "test", "outtest_partial.uvh5")
+    partial_uvh5.initialize_uvh5_file(partial_testfile, clobber=True)
+
+    # check that IOError is raised then when clobber == False
+    with pytest.raises(IOError) as cm:
+        partial_uvh5.initialize_uvh5_file(partial_testfile, clobber=False)
+    assert str(cm.value).startswith("File exists; skipping")
+
+    # clean up
+    os.remove(partial_testfile)
+
+    return
+
 
-    # check that IOError is raised then when clobber == False
-    pytest.raises(IOError, partial_uvh5.initialize_uvh5_file, partial_testfile, clobber=False)
+def test_initialize_uvh5_file_compression_opts(uv_partial_write):
+    """
+    Test initializing a uvh5 file with compression options.
+    """
+    full_uvh5 = uv_partial_write
+    full_uvh5.data_array = None
+    full_uvh5.flag_array = None
+    full_uvh5.nsample_array = None
 
     # add options for compression
-    partial_uvh5.initialize_uvh5_file(partial_testfile, clobber=True, data_compression="lzf",
-                                      flags_compression=None, nsample_compression=None)
+    partial_uvh5 = full_uvh5.copy()
+    partial_testfile = os.path.join(DATA_PATH, "test", "outtest_partial.uvh5")
+    partial_uvh5.initialize_uvh5_file(
+        partial_testfile,
+        clobber=True,
+        data_compression="lzf",
+        flags_compression=None,
+        nsample_compression=None,
+    )
     partial_uvh5.read(partial_testfile, read_data=False)
     assert partial_uvh5 == full_uvh5
 
     # clean up
-    os.remove(testfile)
     os.remove(partial_testfile)
 
     return
 
 
-def test_UVH5SingleIntegrationTime():
+def test_uvh5_single_integration_time(uv_uvfits):
     """
-    Check backwards compatibility warning for files with a single integration time
+    Check backwards compatibility warning for files with a single integration time.
     """
-    uv_in = UVData()
+    uv_in = uv_uvfits
     uv_out = UVData()
-    uvfits_file = os.path.join(DATA_PATH, 'day2_TDEM0003_10s_norx_1src_1spw.uvfits')
     testfile = os.path.join(DATA_PATH, 'test', 'outtest_uvfits.uvh5')
-    uvtest.checkWarnings(uv_in.read_uvfits, [uvfits_file], message='Telescope EVLA is not')
     uv_in.telescope_name = "PAPER"
     uv_in.write_uvh5(testfile, clobber=True)
 
     # change integration_time in file to be a single number
-    with h5py.File(testfile, 'r+') as f:
-        int_time = f['/Header/integration_time'][0]
-        del(f['/Header/integration_time'])
-        f['/Header/integration_time'] = int_time
-    uvtest.checkWarnings(uv_out.read_uvh5, [testfile],
-                         message='outtest_uvfits.uvh5 appears to be an old uvh5 format',
-                         category=DeprecationWarning)
+    with h5py.File(testfile, 'r+') as h5f:
+        int_time = h5f['/Header/integration_time'][0]
+        del(h5f['/Header/integration_time'])
+        h5f['/Header/integration_time'] = int_time
+    uvtest.checkWarnings(
+        uv_out.read_uvh5,
+        [testfile],
+        message='outtest_uvfits.uvh5 appears to be an old uvh5 format',
+        category=DeprecationWarning,
+    )
     assert uv_in == uv_out
 
     # clean up
@@ -977,32 +1341,33 @@ def test_UVH5SingleIntegrationTime():
     return
 
 
-def test_UVH5LstArray():
+def test_uvh5_lst_array(uv_uvfits):
     """
-    Test different cases of the lst_array
+    Test different cases of the lst_array.
     """
-    uv_in = UVData()
+    uv_in = uv_uvfits
     uv_out = UVData()
-    uvfits_file = os.path.join(DATA_PATH, 'day2_TDEM0003_10s_norx_1src_1spw.uvfits')
     testfile = os.path.join(DATA_PATH, 'test', 'outtest_uvfits.uvh5')
-    uvtest.checkWarnings(uv_in.read_uvfits, [uvfits_file], message='Telescope EVLA is not')
     uv_in.telescope_name = "PAPER"
     uv_in.write_uvh5(testfile, clobber=True)
 
     # remove lst_array from file; check that it's correctly computed on read
-    with h5py.File(testfile, 'r+') as f:
-        del(f['/Header/lst_array'])
+    with h5py.File(testfile, 'r+') as h5f:
+        del(h5f['/Header/lst_array'])
     uv_out.read_uvh5(testfile)
     assert uv_in == uv_out
 
     # now change what's in the file and make sure a warning is raised
     uv_in.write_uvh5(testfile, clobber=True)
-    with h5py.File(testfile, 'r+') as f:
-        lst_array = f['/Header/lst_array'][:]
-        del(f['/Header/lst_array'])
-        f['/Header/lst_array'] = 2 * lst_array
-    uvtest.checkWarnings(uv_out.read_uvh5, [testfile],
-                         message='LST values stored in outtest_uvfits.uvh5 are not self-consistent')
+    with h5py.File(testfile, 'r+') as h5f:
+        lst_array = h5f['/Header/lst_array'][:]
+        del(h5f['/Header/lst_array'])
+        h5f['/Header/lst_array'] = 2 * lst_array
+    uvtest.checkWarnings(
+        uv_out.read_uvh5,
+        [testfile],
+        message='LST values stored in outtest_uvfits.uvh5 are not self-consistent',
+    )
     uv_out.lst_array = lst_array
     assert uv_in == uv_out
 
@@ -1012,25 +1377,26 @@ def test_UVH5LstArray():
     return
 
 
-def test_UVH5StringBackCompat():
+def test_uvh5_string_back_compat(uv_uvfits):
     """
-    Test backwards compatibility handling of strings
+    Test backwards compatibility handling of strings.
     """
-    uv_in = UVData()
+    uv_in = uv_uvfits
     uv_out = UVData()
-    uvfits_file = os.path.join(DATA_PATH, 'day2_TDEM0003_10s_norx_1src_1spw.uvfits')
     testfile = os.path.join(DATA_PATH, 'test', 'outtest_uvfits.uvh5')
-    uvtest.checkWarnings(uv_in.read_uvfits, [uvfits_file], message='Telescope EVLA is not')
     uv_in.telescope_name = "PAPER"
     uv_in.write_uvh5(testfile, clobber=True)
 
     # write a string-type data as-is, without casting to np.string_
-    with h5py.File(testfile, 'r+') as f:
-        del(f['Header/instrument'])
-        f['Header/instrument'] = uv_in.instrument
-    uvtest.checkWarnings(uv_out.read_uvh5, [testfile],
-                         message='Strings in metadata of outtest_uvfits.uvh5 are not the correct type',
-                         category=DeprecationWarning)
+    with h5py.File(testfile, 'r+') as h5f:
+        del(h5f['Header/instrument'])
+        h5f['Header/instrument'] = uv_in.instrument
+    uvtest.checkWarnings(
+        uv_out.read_uvh5,
+        [testfile],
+        message='Strings in metadata of outtest_uvfits.uvh5 are not the correct type',
+        category=DeprecationWarning,
+    )
     assert uv_in == uv_out
 
     # clean up
@@ -1039,31 +1405,33 @@ def test_UVH5StringBackCompat():
     return
 
 
-def test_UVH5ReadHeaderSpecialCases():
+def test_uvh5_read_header_special_cases(uv_uvfits):
     """
-    Test special cases values when reading files
+    Test special cases values when reading files.
     """
-    uv_in = UVData()
+    uv_in = uv_uvfits
     uv_out = UVData()
-    uvfits_file = os.path.join(DATA_PATH, 'day2_TDEM0003_10s_norx_1src_1spw.uvfits')
     testfile = os.path.join(DATA_PATH, 'test', 'outtest_uvfits.uvh5')
-    uvtest.checkWarnings(uv_in.read_uvfits, [uvfits_file], message='Telescope EVLA is not')
     uv_in.telescope_name = "PAPER"
     uv_in.write_uvh5(testfile, clobber=True)
 
     # change some of the metadata to trip certain if/else clauses
-    with h5py.File(testfile, 'r+') as f:
-        del(f['Header/history'])
-        del(f['Header/vis_units'])
-        del(f['Header/phase_type'])
-        del(f['Header/latitude'])
-        del(f['Header/longitude'])
-        f['Header/history'] = np.string_('blank history')
-        f['Header/phase_type'] = np.string_('blah')
-        f['Header/latitude'] = uv_in.telescope_location_lat_lon_alt[0]
-        f['Header/longitude'] = uv_in.telescope_location_lat_lon_alt[1]
-    uvtest.checkWarnings(uv_out.read_uvh5, [testfile], category=DeprecationWarning,
-                         message='It seems that the latitude and longitude are in radians')
+    with h5py.File(testfile, 'r+') as h5f:
+        del(h5f['Header/history'])
+        del(h5f['Header/vis_units'])
+        del(h5f['Header/phase_type'])
+        del(h5f['Header/latitude'])
+        del(h5f['Header/longitude'])
+        h5f['Header/history'] = np.string_('blank history')
+        h5f['Header/phase_type'] = np.string_('blah')
+        h5f['Header/latitude'] = uv_in.telescope_location_lat_lon_alt[0]
+        h5f['Header/longitude'] = uv_in.telescope_location_lat_lon_alt[1]
+    uvtest.checkWarnings(
+        uv_out.read_uvh5,
+        [testfile],
+        category=DeprecationWarning,
+        message='It seems that the latitude and longitude are in radians',
+    )
 
     # make input and output values match now
     uv_in.history = uv_out.history
@@ -1080,15 +1448,13 @@ def test_UVH5ReadHeaderSpecialCases():
     return
 
 
-def test_UVH5ReadInts():
+def test_uvh5_read_ints(uv_uvh5):
     """
-    Test reading visibility data saved as integers
+    Test reading visibility data saved as integers.
     """
-    uv_in = UVData()
+    uv_in = uv_uvh5
     uv_out = UVData()
-    uvh5_file = os.path.join(DATA_PATH, 'zen.2458432.34569.uvh5')
     testfile = os.path.join(DATA_PATH, 'test', 'outtest.uvh5')
-    uv_in.read_uvh5(uvh5_file)
     uv_in.write_uvh5(testfile, clobber=True)
 
     # read it back in to make sure data is the same
@@ -1096,28 +1462,39 @@ def test_UVH5ReadInts():
     assert uv_in == uv_out
 
     # now read in as np.complex128
-    uv_in.read_uvh5(uvh5_file, data_array_dtype=np.complex128)
+    uvh5_filename = os.path.join(DATA_PATH, 'zen.2458432.34569.uvh5')
+    uv_in.read_uvh5(uvh5_filename, data_array_dtype=np.complex128)
     assert uv_in == uv_out
     assert uv_in.data_array.dtype == np.dtype(np.complex128)
 
     # clean up
     os.remove(testfile)
 
-    # raise error
-    pytest.raises(ValueError, uv_in.read_uvh5, uvh5_file, data_array_dtype=np.int32)
-
     return
 
 
-def test_UVH5WriteInts():
+def test_uvh5_read_ints_error():
     """
-    Test writing visibility data as integers
+    Test raising an error for passing in an unsupported data_array dtype.
     """
     uv_in = UVData()
+    uvh5_filename = os.path.join(DATA_PATH, "zen.2458432.34569.uvh5")
+
+    # raise error for bogus data_array_dtype
+    with pytest.raises(ValueError) as cm:
+        uv_in.read_uvh5(uvh5_filename, data_array_dtype=np.int32)
+    assert str(cm.value).startswith("data_array_dtype must be np.complex64 or np.complex128")
+
+    return
+
+
+def test_uvh5_write_ints(uv_uvh5):
+    """
+    Test writing visibility data as integers.
+    """
+    uv_in = uv_uvh5
     uv_out = UVData()
-    uvh5_file = os.path.join(DATA_PATH, 'zen.2458432.34569.uvh5')
     testfile = os.path.join(DATA_PATH, 'test', 'outtest.uvh5')
-    uv_in.read_uvh5(uvh5_file)
     uv_in.write_uvh5(testfile, clobber=True, data_write_dtype=_hera_corr_dtype)
 
     # read it back in to make sure data is the same
@@ -1125,8 +1502,8 @@ def test_UVH5WriteInts():
     assert uv_in == uv_out
 
     # also check that the datatype on disk is the right type
-    with h5py.File(testfile, 'r') as f:
-        visdata_dtype = f['Data/visdata'].dtype
+    with h5py.File(testfile, 'r') as h5f:
+        visdata_dtype = h5f['Data/visdata'].dtype
         assert 'r' in visdata_dtype.names
         assert 'i' in visdata_dtype.names
         assert visdata_dtype['r'].kind == 'i'
@@ -1138,9 +1515,9 @@ def test_UVH5WriteInts():
     return
 
 
-def test_UVH5PartialReadInts():
+def test_uvh5_partial_read_ints_antennas():
     """
-    Test reading in only part of a dataset from disk
+    Test reading in only some antennas from disk with integer data type.
     """
     uvh5_uv = UVData()
     uvh5_uv2 = UVData()
@@ -1153,6 +1530,17 @@ def test_UVH5PartialReadInts():
     uvh5_uv2.select(antenna_nums=ants_to_keep)
     assert uvh5_uv == uvh5_uv2
 
+    return
+
+
+def test_uvh5_partial_read_ints_freqs():
+    """
+    Test reading in only some frequencies from disk with integer data type.
+    """
+    uvh5_uv = UVData()
+    uvh5_uv2 = UVData()
+    uvh5_file = os.path.join(DATA_PATH, 'zen.2458432.34569.uvh5')
+
     # select on frequency channels
     chans_to_keep = np.arange(12, 22)
     uvh5_uv.read(uvh5_file, freq_chans=chans_to_keep)
@@ -1160,6 +1548,17 @@ def test_UVH5PartialReadInts():
     uvh5_uv2.select(freq_chans=chans_to_keep)
     assert uvh5_uv == uvh5_uv2
 
+    return
+
+
+def test_uvh5_partial_read_ints_pols():
+    """
+    Test reading in only some polarizations from disk with integer data type.
+    """
+    uvh5_uv = UVData()
+    uvh5_uv2 = UVData()
+    uvh5_file = os.path.join(DATA_PATH, 'zen.2458432.34569.uvh5')
+
     # select on pols
     pols_to_keep = [-5, -6]
     uvh5_uv.read(uvh5_file, polarizations=pols_to_keep)
@@ -1167,65 +1566,135 @@ def test_UVH5PartialReadInts():
     uvh5_uv2.select(polarizations=pols_to_keep)
     assert uvh5_uv == uvh5_uv2
 
+    return
+
+
+def test_uvh5_partial_read_ints_times():
+    """
+    Test reading in only some times from disk with integer data type.
+    """
+    uvh5_uv = UVData()
+    uvh5_uv2 = UVData()
+    uvh5_file = os.path.join(DATA_PATH, 'zen.2458432.34569.uvh5')
+
     # select on read using time_range
+    uvh5_uv.read_uvh5(uvh5_file, read_data=False)
     unique_times = np.unique(uvh5_uv.time_array)
-    uvtest.checkWarnings(uvh5_uv.read, [uvh5_file],
-                         {'time_range': [unique_times[0], unique_times[1]]},
-                         message=['Warning: "time_range" keyword is set'])
+    uvtest.checkWarnings(
+        uvh5_uv.read,
+        [uvh5_file],
+        {'time_range': [unique_times[0], unique_times[1]]},
+        message=['Warning: "time_range" keyword is set'],
+    )
     uvh5_uv2.read(uvh5_file)
     uvh5_uv2.select(times=unique_times[0:2])
     assert uvh5_uv == uvh5_uv2
 
-    # now test selecting on multiple axes
-    # frequencies first
-    uvh5_uv.read(uvh5_file, antenna_nums=ants_to_keep, freq_chans=chans_to_keep,
-                 polarizations=pols_to_keep)
+    return
+
+
+def test_uvh5_partial_read_ints_multi1():
+    """
+    Test select-on-read for multiple axes, frequencies being smallest fraction.
+    """
+    uvh5_uv = UVData()
+    uvh5_uv2 = UVData()
+    uvh5_file = os.path.join(DATA_PATH, 'zen.2458432.34569.uvh5')
+
+    # read frequencies first
+    ants_to_keep = np.array([0, 1])
+    chans_to_keep = np.arange(12, 22)
+    pols_to_keep = [-5, -6]
+    uvh5_uv.read(
+        uvh5_file,
+        antenna_nums=ants_to_keep,
+        freq_chans=chans_to_keep,
+        polarizations=pols_to_keep,
+    )
     uvh5_uv2.read(uvh5_file)
-    uvh5_uv2.select(antenna_nums=ants_to_keep, freq_chans=chans_to_keep,
-                    polarizations=pols_to_keep)
+    uvh5_uv2.select(
+        antenna_nums=ants_to_keep, freq_chans=chans_to_keep, polarizations=pols_to_keep
+    )
     assert uvh5_uv == uvh5_uv2
 
-    # baselines first
+    return
+
+
+def test_uvh5_partial_read_ints_multi2():
+    """
+    Test select-on-read for multiple axes, baselines being smallest fraction.
+    """
+    uvh5_uv = UVData()
+    uvh5_uv2 = UVData()
+    uvh5_file = os.path.join(DATA_PATH, 'zen.2458432.34569.uvh5')
+
+    # read baselines first
     ants_to_keep = np.array([0, 1])
-    uvh5_uv.read(uvh5_file, antenna_nums=ants_to_keep, freq_chans=chans_to_keep,
-                 polarizations=pols_to_keep)
+    chans_to_keep = np.arange(12, 22)
+    pols_to_keep = [-5, -6, -7]
+    uvh5_uv.read(
+        uvh5_file,
+        antenna_nums=ants_to_keep,
+        freq_chans=chans_to_keep,
+        polarizations=pols_to_keep,
+    )
     uvh5_uv2.read(uvh5_file)
-    uvh5_uv2.select(antenna_nums=ants_to_keep, freq_chans=chans_to_keep,
-                    polarizations=pols_to_keep)
+    uvh5_uv2.select(
+        antenna_nums=ants_to_keep,
+        freq_chans=chans_to_keep,
+        polarizations=pols_to_keep,
+    )
     assert uvh5_uv == uvh5_uv2
 
-    # polarizations first
-    ants_to_keep = np.array([0, 1])
+    return
+
+
+def test_uvh5_partial_read_ints_multi3():
+    """
+    Test select-on-read for multiple axes, polarizations being smallest fraction.
+    """
+    uvh5_uv = UVData()
+    uvh5_uv2 = UVData()
+    uvh5_file = os.path.join(DATA_PATH, 'zen.2458432.34569.uvh5')
+
+    # read polarizations first
+    ants_to_keep = np.array([0, 1, 12])
     chans_to_keep = np.arange(12, 64)
-    uvh5_uv.read(uvh5_file, antenna_nums=ants_to_keep, freq_chans=chans_to_keep,
-                 polarizations=pols_to_keep)
+    pols_to_keep = [-5, -6]
+    uvh5_uv.read(
+        uvh5_file,
+        antenna_nums=ants_to_keep,
+        freq_chans=chans_to_keep,
+        polarizations=pols_to_keep,
+    )
     uvh5_uv2.read(uvh5_file)
-    uvh5_uv2.select(antenna_nums=ants_to_keep, freq_chans=chans_to_keep,
-                    polarizations=pols_to_keep)
+    uvh5_uv2.select(
+        antenna_nums=ants_to_keep, freq_chans=chans_to_keep, polarizations=pols_to_keep
+    )
     assert uvh5_uv == uvh5_uv2
 
     return
 
 
-def test_UVH5PartialWriteInts():
+def test_uvh5_partial_write_ints_antapirs(uv_uvh5):
     """
-    Test writing an entire UVH5 file in pieces with integer outputs
+    Test writing an entire UVH5 file in pieces by antpairs using ints.
     """
-    full_uvh5 = UVData()
-    partial_uvh5 = UVData()
-    uvh5_file = os.path.join(DATA_PATH, 'zen.2458432.34569.uvh5')
-    full_uvh5.read_uvh5(uvh5_file)
+    full_uvh5 = uv_uvh5
 
     # delete data arrays in partial file
-    partial_uvh5 = copy.deepcopy(full_uvh5)
+    partial_uvh5 = full_uvh5.copy()
     partial_uvh5.data_array = None
     partial_uvh5.flag_array = None
     partial_uvh5.nsample_array = None
 
     # initialize file on disk
     partial_testfile = os.path.join(DATA_PATH, 'test', 'outtest_partial.uvh5')
-    partial_uvh5.initialize_uvh5_file(partial_testfile, clobber=True,
-                                      data_write_dtype=_hera_corr_dtype)
+    partial_uvh5.initialize_uvh5_file(
+        partial_testfile,
+        clobber=True,
+        data_write_dtype=_hera_corr_dtype,
+    )
 
     # write to file by iterating over antpairpol
     antpairpols = full_uvh5.get_antpairpols()
@@ -1233,22 +1702,39 @@ def test_UVH5PartialWriteInts():
         data = full_uvh5.get_data(key, squeeze='none')
         flags = full_uvh5.get_flags(key, squeeze='none')
         nsamples = full_uvh5.get_nsamples(key, squeeze='none')
-        partial_uvh5.write_uvh5_part(partial_testfile, data, flags, nsamples,
-                                     bls=key)
+        partial_uvh5.write_uvh5_part(
+            partial_testfile, data, flags, nsamples, bls=key
+        )
 
     # now read in the full file and make sure that it matches the original
     partial_uvh5.read(partial_testfile)
     assert full_uvh5 == partial_uvh5
 
-    # start over, and write frequencies
-    partial_uvh5 = copy.deepcopy(full_uvh5)
+    # clean up
+    os.remove(partial_testfile)
+
+    return
+
+
+def test_uvh5_partial_write_ints_frequencies(uv_uvh5):
+    """
+    Test writing an entire UVH5 file in pieces by frequency using ints.
+    """
+    full_uvh5 = uv_uvh5
+
+    # delete data arrays in partial file
+    partial_uvh5 = full_uvh5.copy()
     partial_uvh5.data_array = None
     partial_uvh5.flag_array = None
     partial_uvh5.nsample_array = None
 
     # initialize file on disk
-    partial_uvh5.initialize_uvh5_file(partial_testfile, clobber=True,
-                                      data_write_dtype=_hera_corr_dtype)
+    partial_testfile = os.path.join(DATA_PATH, 'test', 'outtest_partial.uvh5')
+    partial_uvh5.initialize_uvh5_file(
+        partial_testfile, clobber=True, data_write_dtype=_hera_corr_dtype
+    )
+
+    # only write certain frequencies
     Nfreqs = full_uvh5.Nfreqs
     Hfreqs = Nfreqs // 2
     freqs1 = np.arange(Hfreqs)
@@ -1256,27 +1742,45 @@ def test_UVH5PartialWriteInts():
     data = full_uvh5.data_array[:, :, freqs1, :]
     flags = full_uvh5.flag_array[:, :, freqs1, :]
     nsamples = full_uvh5.nsample_array[:, :, freqs1, :]
-    partial_uvh5.write_uvh5_part(partial_testfile, data, flags, nsamples,
-                                 freq_chans=freqs1)
+    partial_uvh5.write_uvh5_part(
+        partial_testfile, data, flags, nsamples, freq_chans=freqs1
+    )
     data = full_uvh5.data_array[:, :, freqs2, :]
     flags = full_uvh5.flag_array[:, :, freqs2, :]
     nsamples = full_uvh5.nsample_array[:, :, freqs2, :]
-    partial_uvh5.write_uvh5_part(partial_testfile, data, flags, nsamples,
-                                 freq_chans=freqs2)
+    partial_uvh5.write_uvh5_part(
+        partial_testfile, data, flags, nsamples, freq_chans=freqs2
+    )
 
     # read in the full file and make sure it matches
     partial_uvh5.read(partial_testfile)
     assert full_uvh5 == partial_uvh5
 
-    # start over, write chunks of blts
-    partial_uvh5 = copy.deepcopy(full_uvh5)
+    # clean up
+    os.remove(partial_testfile)
+
+    return
+
+
+def test_uvh5_partial_write_ints_blts(uv_uvh5):
+    """
+    Test writing an entire UVH5 file in pieces by blt using ints.
+    """
+    full_uvh5 = uv_uvh5
+
+    # delete data arrays in partial file
+    partial_uvh5 = full_uvh5.copy()
     partial_uvh5.data_array = None
     partial_uvh5.flag_array = None
     partial_uvh5.nsample_array = None
 
     # initialize file on disk
-    partial_uvh5.initialize_uvh5_file(partial_testfile, clobber=True,
-                                      data_write_dtype=_hera_corr_dtype)
+    partial_testfile = os.path.join(DATA_PATH, 'test', 'outtest_partial.uvh5')
+    partial_uvh5.initialize_uvh5_file(
+        partial_testfile, clobber=True, data_write_dtype=_hera_corr_dtype
+    )
+
+    # only write certain blts
     Nblts = full_uvh5.Nblts
     Hblts = Nblts // 2
     blts1 = np.arange(Hblts)
@@ -1284,27 +1788,45 @@ def test_UVH5PartialWriteInts():
     data = full_uvh5.data_array[blts1, :, :, :]
     flags = full_uvh5.flag_array[blts1, :, :, :]
     nsamples = full_uvh5.nsample_array[blts1, :, :, :]
-    partial_uvh5.write_uvh5_part(partial_testfile, data, flags, nsamples,
-                                 blt_inds=blts1)
+    partial_uvh5.write_uvh5_part(
+        partial_testfile, data, flags, nsamples, blt_inds=blts1
+    )
     data = full_uvh5.data_array[blts2, :, :, :]
     flags = full_uvh5.flag_array[blts2, :, :, :]
     nsamples = full_uvh5.nsample_array[blts2, :, :, :]
-    partial_uvh5.write_uvh5_part(partial_testfile, data, flags, nsamples,
-                                 blt_inds=blts2)
+    partial_uvh5.write_uvh5_part(
+        partial_testfile, data, flags, nsamples, blt_inds=blts2
+    )
 
     # read in the full file and make sure it matches
     partial_uvh5.read(partial_testfile)
     assert full_uvh5 == partial_uvh5
 
-    # start over, write groups of pols
-    partial_uvh5 = copy.deepcopy(full_uvh5)
+    # clean up
+    os.remove(partial_testfile)
+
+    return
+
+
+def test_uvh5_partial_write_ints_pols(uv_uvh5):
+    """
+    Test writing an entire UVH5 file in pieces by polarization using ints.
+    """
+    full_uvh5 = uv_uvh5
+
+    # delete data arrays in partial file
+    partial_uvh5 = full_uvh5.copy()
     partial_uvh5.data_array = None
     partial_uvh5.flag_array = None
     partial_uvh5.nsample_array = None
 
     # initialize file on disk
-    partial_uvh5.initialize_uvh5_file(partial_testfile, clobber=True,
-                                      data_write_dtype=_hera_corr_dtype)
+    partial_testfile = os.path.join(DATA_PATH, 'test', 'outtest_partial.uvh5')
+    partial_uvh5.initialize_uvh5_file(
+        partial_testfile, clobber=True, data_write_dtype=_hera_corr_dtype
+    )
+
+    # only write certain polarizations
     Npols = full_uvh5.Npols
     Hpols = Npols // 2
     pols1 = np.arange(Hpols)
@@ -1312,13 +1834,23 @@ def test_UVH5PartialWriteInts():
     data = full_uvh5.data_array[:, :, :, pols1]
     flags = full_uvh5.flag_array[:, :, :, pols1]
     nsamples = full_uvh5.nsample_array[:, :, :, pols1]
-    partial_uvh5.write_uvh5_part(partial_testfile, data, flags, nsamples,
-                                 polarizations=full_uvh5.polarization_array[:Hpols])
+    partial_uvh5.write_uvh5_part(
+        partial_testfile,
+        data,
+        flags,
+        nsamples,
+        polarizations=full_uvh5.polarization_array[:Hpols],
+    )
     data = full_uvh5.data_array[:, :, :, pols2]
     flags = full_uvh5.flag_array[:, :, :, pols2]
     nsamples = full_uvh5.nsample_array[:, :, :, pols2]
-    partial_uvh5.write_uvh5_part(partial_testfile, data, flags, nsamples,
-                                 polarizations=full_uvh5.polarization_array[Hpols:])
+    partial_uvh5.write_uvh5_part(
+        partial_testfile,
+        data,
+        flags,
+        nsamples,
+        polarizations=full_uvh5.polarization_array[Hpols:],
+    )
 
     # read in the full file and make sure it matches
     partial_uvh5.read(partial_testfile)
@@ -1337,8 +1869,8 @@ def test_read_complex_astype():
     test_data = np.zeros(test_data_shape, dtype=np.complex64)
     test_data.real = 1.
     test_data.imag = 2.
-    with h5py.File(test_file, 'w') as f:
-        dgrp = f.create_group('Data')
+    with h5py.File(test_file, 'w') as h5f:
+        dgrp = h5f.create_group('Data')
         dset = dgrp.create_dataset('testdata', test_data_shape,
                                    dtype=_hera_corr_dtype)
         with dset.astype(_hera_corr_dtype):
@@ -1347,17 +1879,40 @@ def test_read_complex_astype():
 
     # test that reading the data back in works as expected
     indices = (np.s_[:], np.s_[:], np.s_[:], np.s_[:])
-    with h5py.File(test_file, 'r') as f:
-        dset = f['Data/testdata']
+    with h5py.File(test_file, 'r') as h5f:
+        dset = h5f['Data/testdata']
         file_data = uvh5._read_complex_astype(dset, indices, np.complex64)
 
     assert np.allclose(file_data, test_data)
 
-    # test errors
+    # clean up
+    os.remove(test_file)
+
+    return
+
+
+def test_read_complex_astype_errors():
+    # make a testfile with a test dataset
+    test_file = os.path.join(DATA_PATH, 'test', 'test_file.h5')
+    test_data_shape = (2, 3, 4, 5)
+    test_data = np.zeros(test_data_shape, dtype=np.complex64)
+    test_data.real = 1.
+    test_data.imag = 2.
+    with h5py.File(test_file, 'w') as h5f:
+        dgrp = h5f.create_group('Data')
+        dset = dgrp.create_dataset('testdata', test_data_shape,
+                                   dtype=_hera_corr_dtype)
+        with dset.astype(_hera_corr_dtype):
+            dset[:, :, :, :, 'r'] = test_data.real
+            dset[:, :, :, :, 'i'] = test_data.imag
+
     # test passing in a forbidden output datatype
-    with h5py.File(test_file, 'r') as f:
-        dset = f['Data/testdata']
-        pytest.raises(ValueError, uvh5._read_complex_astype, dset, indices, np.int32)
+    indices = (np.s_[:], np.s_[:], np.s_[:], np.s_[:])
+    with h5py.File(test_file, 'r') as h5f:
+        dset = h5f['Data/testdata']
+        with pytest.raises(ValueError) as cm:
+            uvh5._read_complex_astype(dset, indices, np.int32)
+        assert str(cm.value).startswith("output datatype must be one of (complex")
 
     # clean up
     os.remove(test_file)
@@ -1372,16 +1927,16 @@ def test_write_complex_astype():
     test_data = np.zeros(test_data_shape, dtype=np.complex64)
     test_data.real = 1.
     test_data.imag = 2.
-    with h5py.File(test_file, 'w') as f:
-        dgrp = f.create_group('Data')
+    with h5py.File(test_file, 'w') as h5f:
+        dgrp = h5f.create_group('Data')
         dset = dgrp.create_dataset('testdata', test_data_shape,
                                    dtype=_hera_corr_dtype)
         inds = (np.s_[:], np.s_[:], np.s_[:], np.s_[:])
         uvh5._write_complex_astype(test_data, dset, inds)
 
     # read the data back in to confirm it's right
-    with h5py.File(test_file, 'r') as f:
-        dset = f['Data/testdata']
+    with h5py.File(test_file, 'r') as h5f:
+        dset = h5f['Data/testdata']
         file_data = np.zeros(test_data_shape, dtype=np.complex64)
         with dset.astype(_hera_corr_dtype):
             file_data.real = dset['r'][:, :, :, :]
@@ -1394,51 +1949,31 @@ def test_write_complex_astype():
 
 def test_check_uvh5_dtype_errors():
     # test passing in something that's not a dtype
-    pytest.raises(ValueError, uvh5._check_uvh5_dtype, 'hi')
+    with pytest.raises(ValueError) as cm:
+        uvh5._check_uvh5_dtype('hi')
+    assert str(cm.value).startswith("dtype in a uvh5 file must be a numpy dtype")
 
     # test using a dtype with bad field names
     dtype = np.dtype([('a', '<i4'), ('b', '<i4')])
-    pytest.raises(ValueError, uvh5._check_uvh5_dtype, dtype)
+    with pytest.raises(ValueError) as cm:
+        uvh5._check_uvh5_dtype(dtype)
+    assert str(cm.value).startswith("dtype must be a compound datatype")
 
     # test having different types for 'r' and 'i' fields
     dtype = np.dtype([('r', '<i4'), ('i', '<f4')])
-    pytest.raises(ValueError, uvh5._check_uvh5_dtype, dtype)
+    with pytest.raises(ValueError) as cm:
+        uvh5._check_uvh5_dtype(dtype)
+    assert str(cm.value).startswith("dtype must have the same kind")
 
     return
 
 
-def test_UVH5PartialWriteIntsIrregular():
+def test_uvh5_partial_write_ints_irregular_blt(uv_uvh5):
     """
-    Test writing a uvh5 file using irregular intervals
+    Test writing a uvh5 file using irregular interval for blt and integer dtype.
     """
-    def initialize_with_zeros_ints(uvd, filename):
-        """
-        Initialize a file with all zeros for data arrays
-        """
-        uvd.initialize_uvh5_file(filename, clobber=True, data_write_dtype=_hera_corr_dtype)
-        data_shape = (uvd.Nblts, 1, uvd.Nfreqs, uvd.Npols)
-        data = np.zeros(data_shape, dtype=np.complex64)
-        flags = np.zeros(data_shape, dtype=np.bool)
-        nsamples = np.zeros(data_shape, dtype=np.float32)
-        with h5py.File(filename, 'r+') as f:
-            dgrp = f['/Data']
-            data_dset = dgrp['visdata']
-            flags_dset = dgrp['flags']
-            nsample_dset = dgrp['nsamples']
-            with data_dset.astype(_hera_corr_dtype):
-                data_dset[:, :, :, :, 'r'] = data.real
-                data_dset[:, :, :, :, 'i'] = data.imag
-            flags_dset = flags
-            nsample_dset = nsamples
-        return
-
-    full_uvh5 = UVData()
-    partial_uvh5 = UVData()
-    uvh5_file = os.path.join(DATA_PATH, 'zen.2458432.34569.uvh5')
-    full_uvh5.read(uvh5_file)
-
-    # delete data arrays in partial file
-    partial_uvh5 = copy.deepcopy(full_uvh5)
+    full_uvh5 = uv_uvh5
+    partial_uvh5 = full_uvh5.copy()
     partial_uvh5.data_array = None
     partial_uvh5.flag_array = None
     partial_uvh5.nsample_array = None
@@ -1469,9 +2004,18 @@ def test_UVH5PartialWriteIntsIrregular():
     partial_uvh5_file.read(partial_testfile)
     assert partial_uvh5_file == partial_uvh5
 
-    # do it again, with a single frequency
-    # reinitialize
-    partial_uvh5 = copy.deepcopy(full_uvh5)
+    # clean up
+    os.remove(partial_testfile)
+
+    return
+
+
+def test_uvh5_partial_write_ints_irregular_freq(uv_uvh5):
+    """
+    Test writing a uvh5 file using irregular interval for freq and integer dtype.
+    """
+    full_uvh5 = uv_uvh5
+    partial_uvh5 = full_uvh5.copy()
     partial_uvh5.data_array = None
     partial_uvh5.flag_array = None
     partial_uvh5.nsample_array = None
@@ -1490,8 +2034,9 @@ def test_UVH5PartialWriteIntsIrregular():
     data = full_uvh5.data_array[:, :, freq_inds, :]
     flags = full_uvh5.flag_array[:, :, freq_inds, :]
     nsamples = full_uvh5.nsample_array[:, :, freq_inds, :]
-    partial_uvh5.write_uvh5_part(partial_testfile, data, flags, nsamples,
-                                 freq_chans=freq_inds)
+    partial_uvh5.write_uvh5_part(
+        partial_testfile, data, flags, nsamples, freq_chans=freq_inds
+    )
 
     # also write the arrays to the partial object
     partial_uvh5.data_array[:, :, freq_inds, :] = data
@@ -1503,9 +2048,18 @@ def test_UVH5PartialWriteIntsIrregular():
     partial_uvh5_file.read(partial_testfile)
     assert partial_uvh5_file == partial_uvh5
 
-    # do it again, with a single polarization
-    # reinitialize
-    partial_uvh5 = copy.deepcopy(full_uvh5)
+    # clean up
+    os.remove(partial_testfile)
+
+    return
+
+
+def test_uvh5_partial_write_ints_irregular_pol(uv_uvh5):
+    """
+    Test writing a uvh5 file using irregular interval for pol and integer dtype.
+    """
+    full_uvh5 = uv_uvh5
+    partial_uvh5 = full_uvh5.copy()
     partial_uvh5.data_array = None
     partial_uvh5.flag_array = None
     partial_uvh5.nsample_array = None
@@ -1524,8 +2078,13 @@ def test_UVH5PartialWriteIntsIrregular():
     data = full_uvh5.data_array[:, :, :, pol_inds]
     flags = full_uvh5.flag_array[:, :, :, pol_inds]
     nsamples = full_uvh5.nsample_array[:, :, :, pol_inds]
-    partial_uvh5.write_uvh5_part(partial_testfile, data, flags, nsamples,
-                                 polarizations=partial_uvh5.polarization_array[pol_inds])
+    partial_uvh5.write_uvh5_part(
+        partial_testfile,
+        data,
+        flags,
+        nsamples,
+        polarizations=partial_uvh5.polarization_array[pol_inds],
+    )
 
     # also write the arrays to the partial object
     partial_uvh5.data_array[:, :, :, pol_inds] = data
@@ -1537,9 +2096,18 @@ def test_UVH5PartialWriteIntsIrregular():
     partial_uvh5_file.read(partial_testfile)
     assert partial_uvh5_file == partial_uvh5
 
-    # test irregularly spaced blts and freqs
-    # reinitialize
-    partial_uvh5 = copy.deepcopy(full_uvh5)
+    # clean up
+    os.remove(partial_testfile)
+
+    return
+
+
+def test_uvh5_partial_write_ints_irregular_multi1(uv_uvh5):
+    """
+    Test writing a uvh5 file using irregular interval for blt and freq and integer dtype.
+    """
+    full_uvh5 = uv_uvh5
+    partial_uvh5 = full_uvh5.copy()
     partial_uvh5.data_array = None
     partial_uvh5.flag_array = None
     partial_uvh5.nsample_array = None
@@ -1565,9 +2133,12 @@ def test_UVH5PartialWriteIntsIrregular():
             data[iblt, :, ifreq, :] = full_uvh5.data_array[blt_idx, :, freq_idx, :]
             flags[iblt, :, ifreq, :] = full_uvh5.flag_array[blt_idx, :, freq_idx, :]
             nsamples[iblt, :, ifreq, :] = full_uvh5.nsample_array[blt_idx, :, freq_idx, :]
-    uvtest.checkWarnings(partial_uvh5.write_uvh5_part, [partial_testfile, data, flags, nsamples],
-                         {'blt_inds': blt_inds, 'freq_chans': freq_inds},
-                         message='Selected frequencies are not evenly spaced')
+    uvtest.checkWarnings(
+        partial_uvh5.write_uvh5_part,
+        [partial_testfile, data, flags, nsamples],
+        {'blt_inds': blt_inds, 'freq_chans': freq_inds},
+        message='Selected frequencies are not evenly spaced',
+    )
 
     # also write the arrays to the partial object
     for iblt, blt_idx in enumerate(blt_inds):
@@ -1581,9 +2152,18 @@ def test_UVH5PartialWriteIntsIrregular():
     partial_uvh5_file.read(partial_testfile)
     assert partial_uvh5_file == partial_uvh5
 
-    # test irregularly spaced freqs and pols
-    # reinitialize
-    partial_uvh5 = copy.deepcopy(full_uvh5)
+    # clean up
+    os.remove(partial_testfile)
+
+    return
+
+
+def test_uvh5_partial_write_ints_irregular_multi2(uv_uvh5):
+    """
+    Test writing a uvh5 file using irregular interval for freq and pol and integer dtype.
+    """
+    full_uvh5 = uv_uvh5
+    partial_uvh5 = full_uvh5.copy()
     partial_uvh5.data_array = None
     partial_uvh5.flag_array = None
     partial_uvh5.nsample_array = None
@@ -1597,7 +2177,7 @@ def test_UVH5PartialWriteIntsIrregular():
     partial_uvh5.flag_array = np.zeros_like(full_uvh5.flag_array, dtype=np.bool)
     partial_uvh5.nsample_array = np.zeros_like(full_uvh5.nsample_array, dtype=np.float32)
 
-    # define blts and freqs
+    # define freqs and pols
     freq_inds = [0, 1, 2, 7]
     pol_inds = [0, 1, 3]
     data_shape = (full_uvh5.Nblts, 1, len(freq_inds), len(pol_inds))
@@ -1609,10 +2189,16 @@ def test_UVH5PartialWriteIntsIrregular():
             data[:, :, ifreq, ipol] = full_uvh5.data_array[:, :, freq_idx, pol_idx]
             flags[:, :, ifreq, ipol] = full_uvh5.flag_array[:, :, freq_idx, pol_idx]
             nsamples[:, :, ifreq, ipol] = full_uvh5.nsample_array[:, :, freq_idx, pol_idx]
-    uvtest.checkWarnings(partial_uvh5.write_uvh5_part, [partial_testfile, data, flags, nsamples],
-                         {'freq_chans': freq_inds, 'polarizations': full_uvh5.polarization_array[pol_inds]},
-                         nwarnings=2, message=['Selected frequencies are not evenly spaced',
-                                               'Selected polarization values are not evenly spaced'])
+    uvtest.checkWarnings(
+        partial_uvh5.write_uvh5_part,
+        [partial_testfile, data, flags, nsamples],
+        {'freq_chans': freq_inds, 'polarizations': full_uvh5.polarization_array[pol_inds]},
+        nwarnings=2,
+        message=[
+            'Selected frequencies are not evenly spaced',
+            'Selected polarization values are not evenly spaced',
+        ],
+    )
 
     # also write the arrays to the partial object
     for ifreq, freq_idx in enumerate(freq_inds):
@@ -1626,9 +2212,18 @@ def test_UVH5PartialWriteIntsIrregular():
     partial_uvh5_file.read(partial_testfile)
     assert partial_uvh5_file == partial_uvh5
 
-    # test irregularly spaced blts and pols
-    # reinitialize
-    partial_uvh5 = copy.deepcopy(full_uvh5)
+    # clean up
+    os.remove(partial_testfile)
+
+    return
+
+
+def test_uvh5_partial_write_ints_irregular_multi3(uv_uvh5):
+    """
+    Test writing a uvh5 file using irregular interval for blt and pol and integer dtype.
+    """
+    full_uvh5 = uv_uvh5
+    partial_uvh5 = full_uvh5.copy()
     partial_uvh5.data_array = None
     partial_uvh5.flag_array = None
     partial_uvh5.nsample_array = None
@@ -1642,7 +2237,7 @@ def test_UVH5PartialWriteIntsIrregular():
     partial_uvh5.flag_array = np.zeros_like(full_uvh5.flag_array, dtype=np.bool)
     partial_uvh5.nsample_array = np.zeros_like(full_uvh5.nsample_array, dtype=np.float32)
 
-    # define blts and freqs
+    # define blts and pols
     blt_inds = [0, 1, 2, 7]
     pol_inds = [0, 1, 3]
     data_shape = (len(blt_inds), 1, full_uvh5.Nfreqs, len(pol_inds))
@@ -1654,9 +2249,12 @@ def test_UVH5PartialWriteIntsIrregular():
             data[iblt, :, :, ipol] = full_uvh5.data_array[blt_idx, :, :, pol_idx]
             flags[iblt, :, :, ipol] = full_uvh5.flag_array[blt_idx, :, :, pol_idx]
             nsamples[iblt, :, :, ipol] = full_uvh5.nsample_array[blt_idx, :, :, pol_idx]
-    uvtest.checkWarnings(partial_uvh5.write_uvh5_part, [partial_testfile, data, flags, nsamples],
-                         {'blt_inds': blt_inds, 'polarizations': full_uvh5.polarization_array[pol_inds]},
-                         message='Selected polarization values are not evenly spaced')
+    uvtest.checkWarnings(
+        partial_uvh5.write_uvh5_part,
+        [partial_testfile, data, flags, nsamples],
+        {'blt_inds': blt_inds, 'polarizations': full_uvh5.polarization_array[pol_inds]},
+        message='Selected polarization values are not evenly spaced',
+    )
 
     # also write the arrays to the partial object
     for iblt, blt_idx in enumerate(blt_inds):
@@ -1670,54 +2268,18 @@ def test_UVH5PartialWriteIntsIrregular():
     partial_uvh5_file.read(partial_testfile)
     assert partial_uvh5_file == partial_uvh5
 
-    # test irregularly spaced freqs and pols
-    # reinitialize
-    partial_uvh5 = copy.deepcopy(full_uvh5)
-    partial_uvh5.data_array = None
-    partial_uvh5.flag_array = None
-    partial_uvh5.nsample_array = None
-
-    # initialize file on disk
-    partial_testfile = os.path.join(DATA_PATH, 'test', 'outtest_partial.uvh5')
-    initialize_with_zeros_ints(partial_uvh5, partial_testfile)
-
-    # make a mostly empty object in memory to match what we'll write to disk
-    partial_uvh5.data_array = np.zeros_like(full_uvh5.data_array, dtype=np.complex64)
-    partial_uvh5.flag_array = np.zeros_like(full_uvh5.flag_array, dtype=np.bool)
-    partial_uvh5.nsample_array = np.zeros_like(full_uvh5.nsample_array, dtype=np.float32)
-
-    # define blts and freqs
-    freq_inds = [0, 1, 2, 7]
-    pol_inds = [0, 1, 3]
-    data_shape = (full_uvh5.Nblts, 1, len(freq_inds), len(pol_inds))
-    data = np.zeros(data_shape, dtype=np.complex64)
-    flags = np.zeros(data_shape, dtype=np.bool)
-    nsamples = np.zeros(data_shape, dtype=np.float32)
-    for ifreq, freq_idx in enumerate(freq_inds):
-        for ipol, pol_idx in enumerate(pol_inds):
-            data[:, :, ifreq, ipol] = full_uvh5.data_array[:, :, freq_idx, pol_idx]
-            flags[:, :, ifreq, ipol] = full_uvh5.flag_array[:, :, freq_idx, pol_idx]
-            nsamples[:, :, ifreq, ipol] = full_uvh5.nsample_array[:, :, freq_idx, pol_idx]
-    uvtest.checkWarnings(partial_uvh5.write_uvh5_part, [partial_testfile, data, flags, nsamples],
-                         {'freq_chans': freq_inds, 'polarizations': full_uvh5.polarization_array[pol_inds]},
-                         nwarnings=2, message=['Selected frequencies are not evenly spaced',
-                                               'Selected polarization values are not evenly spaced'])
+    # clean up
+    os.remove(partial_testfile)
 
-    # also write the arrays to the partial object
-    for ifreq, freq_idx in enumerate(freq_inds):
-        for ipol, pol_idx in enumerate(pol_inds):
-            partial_uvh5.data_array[:, :, freq_idx, pol_idx] = data[:, :, ifreq, ipol]
-            partial_uvh5.flag_array[:, :, freq_idx, pol_idx] = flags[:, :, ifreq, ipol]
-            partial_uvh5.nsample_array[:, :, freq_idx, pol_idx] = nsamples[:, :, ifreq, ipol]
+    return
 
-    # read in the file and make sure it matches
-    partial_uvh5_file = UVData()
-    partial_uvh5_file.read(partial_testfile)
-    assert partial_uvh5_file == partial_uvh5
 
-    # test irregularly spaced everything
-    # reinitialize
-    partial_uvh5 = copy.deepcopy(full_uvh5)
+def test_uvh5_partial_write_ints_irregular_multi4(uv_uvh5):
+    """
+    Test writing a uvh5 file using irregular interval for all axes and integer dtype.
+    """
+    full_uvh5 = uv_uvh5
+    partial_uvh5 = full_uvh5.copy()
     partial_uvh5.data_array = None
     partial_uvh5.flag_array = None
     partial_uvh5.nsample_array = None
@@ -1745,11 +2307,20 @@ def test_UVH5PartialWriteIntsIrregular():
                 data[iblt, :, ifreq, ipol] = full_uvh5.data_array[blt_idx, :, freq_idx, pol_idx]
                 flags[iblt, :, ifreq, ipol] = full_uvh5.flag_array[blt_idx, :, freq_idx, pol_idx]
                 nsamples[iblt, :, ifreq, ipol] = full_uvh5.nsample_array[blt_idx, :, freq_idx, pol_idx]
-    uvtest.checkWarnings(partial_uvh5.write_uvh5_part, [partial_testfile, data, flags, nsamples],
-                         {'blt_inds': blt_inds, 'freq_chans': freq_inds,
-                          'polarizations': full_uvh5.polarization_array[pol_inds]},
-                         nwarnings=2, message=['Selected frequencies are not evenly spaced',
-                                               'Selected polarization values are not evenly spaced'])
+    uvtest.checkWarnings(
+        partial_uvh5.write_uvh5_part,
+        [partial_testfile, data, flags, nsamples],
+        {
+            'blt_inds': blt_inds,
+            'freq_chans': freq_inds,
+            'polarizations': full_uvh5.polarization_array[pol_inds],
+        },
+        nwarnings=2,
+        message=[
+            'Selected frequencies are not evenly spaced',
+            'Selected polarization values are not evenly spaced',
+        ],
+    )
 
     # also write the arrays to the partial object
     for iblt, blt_idx in enumerate(blt_inds):
@@ -1771,19 +2342,17 @@ def test_UVH5PartialWriteIntsIrregular():
 
 
 @pytest.mark.skipif(not six.PY3, reason="Skipping. This test is only relevant in python3.")
-def test_antenna_names_not_list():
+def test_antenna_names_not_list(uv_uvfits):
     """Test if antenna_names is cast to an array, dimensions are preserved in np.string_ call during uvh5 write."""
-    uv_in = UVData()
+    uv_in = uv_uvfits
     uv_out = UVData()
-    uvfits_file = os.path.join(DATA_PATH, 'day2_TDEM0003_10s_norx_1src_1spw.uvfits')
     testfile = os.path.join(DATA_PATH, 'test', 'outtest_uvfits_ant_names.uvh5')
-    uvtest.checkWarnings(uv_in.read_uvfits, [uvfits_file], message='Telescope EVLA is not')
 
     # simulate a user defining antenna names as an array of unicode
     uv_in.antenna_names = np.array(uv_in.antenna_names, dtype='U')
 
     uv_in.write_uvh5(testfile, clobber=True)
-    uvtest.checkWarnings(uv_out.read, [testfile], message='Telescope EVLA is not')
+    uv_out.read(testfile)
 
     # recast as list since antenna names should be a list and will be cast as list on read
     uv_in.antenna_names = uv_in.antenna_names.tolist()
@@ -1793,3 +2362,21 @@ def test_antenna_names_not_list():
     os.remove(testfile)
 
     return
+
+
+def test_eq_coeffs_roundtrip(uv_uvfits):
+    """Test reading and writing objects with eq_coeffs defined"""
+    uv_in = uv_uvfits
+    uv_out = UVData()
+    testfile = os.path.join(DATA_PATH, "test", "outtest_eq_coeffs.uvh5")
+    uv_in.eq_coeffs = np.ones((uv_in.Nants_telescope, uv_in.Nfreqs))
+    uv_in.eq_coeffs_convention = "divide"
+    uv_in.write_uvh5(testfile, clobber=True)
+    uv_out.read(testfile)
+
+    assert uv_in == uv_out
+
+    # clean up
+    os.remove(testfile)
+
+    return