diff --git a/bapsflib/_hdf/maps/controls/sixk.py b/bapsflib/_hdf/maps/controls/sixk.py
index 1405b58..f300371 100644
--- a/bapsflib/_hdf/maps/controls/sixk.py
+++ b/bapsflib/_hdf/maps/controls/sixk.py
@@ -60,7 +60,7 @@ class HDFMapControl6K(HDFMapControlTemplate):
         # TODO: HOW TO ADD MOTION LIST TO DICT
         # - right now, the dataset has to be read which has the
         #   potential for creating long mapping times
-        # - this is probably best left to HDFReadControl
+        # - this is probably best left to HDFReadControls
         #
 
         # build 'motion list' and 'probe list'
diff --git a/bapsflib/_hdf/maps/controls/templates.py b/bapsflib/_hdf/maps/controls/templates.py
index 4fe7a39..c39d53b 100644
--- a/bapsflib/_hdf/maps/controls/templates.py
+++ b/bapsflib/_hdf/maps/controls/templates.py
@@ -77,7 +77,7 @@ class HDFMapControlTemplate(ABC):
         """
         Dictionary containing all the relevant mapping information to
         translate the HDF5 data into a numpy array by
-        :class:`~bapsflib._hdf.utils.hdfreadcontrol.HDFReadControl`.
+        :class:`~bapsflib._hdf.utils.hdfreadcontrols.HDFReadControls`.
 
         **-- Constructing** :code:`configs` **--**
 
@@ -92,7 +92,7 @@ class HDFMapControlTemplate(ABC):
         required keys (:code:`'dset paths'`, :code:`'shotnum'`, and
         :code:`'state values'`) and optional keys.  Any optional key is
         considered as meta-info for the device and is added to the
-        :attr:`~bapsflib._hdf.utils.hdfreadcontrol.HDFReadControl.info`
+        :attr:`~bapsflib._hdf.utils.hdfreadcontrols.HDFReadControls.info`
         dictionary when the numpy array is constructed.  The required
         keys constitute the mapping for constructing the numpy array
         and are explained in the table below.
@@ -134,7 +134,7 @@ class HDFMapControlTemplate(ABC):
             is the numpy :code:`dtype` of the data.  This all defines
             the numpy :code:`dtype` of the :code:`'shotnum'` field in
             the
-            :class:`~bapsflib._hdf.utils.hdfreadcontrol.HDFReadControl`
+            :class:`~bapsflib._hdf.utils.hdfreadcontrols.HDFReadControls`
             constructed numpy array.
             "
             "::
@@ -153,7 +153,7 @@ class HDFMapControlTemplate(ABC):
                 }
 
             will tell
-            :class:`~bapsflib._hdf.utils.hdfreadcontrol.HDFReadControl`
+            :class:`~bapsflib._hdf.utils.hdfreadcontrols.HDFReadControls`
             to construct a numpy array with a the :code:`'xyz'` field.
             This field would be a 3-element array of
             :code:`numpy.float32`, where the :code:`'x'` field of the
diff --git a/bapsflib/_hdf/utils/__init__.py b/bapsflib/_hdf/utils/__init__.py
index b65ab79..7168ba0 100644
--- a/bapsflib/_hdf/utils/__init__.py
+++ b/bapsflib/_hdf/utils/__init__.py
@@ -12,8 +12,8 @@
 This package contains an assortment of utility classes used to
 access and interface with the HDF5 files generated at BaPSF.
 """
-from . import (file, hdfoverview, hdfreadcontrol, hdfreaddata,
+from . import (file, hdfoverview, hdfreadcontrols, hdfreaddata,
                hdfreadmsi, helpers)
 
-__all__ = ['file', 'hdfoverview', 'hdfreadcontrol', 'hdfreaddata',
+__all__ = ['file', 'hdfoverview', 'hdfreadcontrols.py', 'hdfreaddata',
            'hdfreadmsi', 'helpers']
diff --git a/bapsflib/_hdf/utils/file.py b/bapsflib/_hdf/utils/file.py
index fde7c9e..4f4c412 100644
--- a/bapsflib/_hdf/utils/file.py
+++ b/bapsflib/_hdf/utils/file.py
@@ -142,7 +142,7 @@ class File(h5py.File):
                       silent=False, **kwargs):
         """
         Reads data from control device datasets.  See
-        :class:`~.hdfreadcontrol.HDFReadControl` for more detail.
+        :class:`~.hdfreadcontrols.HDFReadControls` for more detail.
 
         :param controls:
 
@@ -168,8 +168,8 @@ class File(h5py.File):
             to be the intersection of :data:`shotnum` and the shot
             numbers contained in each control device dataset.
             :code:`False` will return the union instead of the
-            intersection, minus :math:`shotnum \le 0`. (see
-            :class:`~.hdfreadcontrol.HDFReadControl`
+            intersection, minus :math:`shotnum \\le 0`. (see
+            :class:`~.hdfreadcontrols.HDFReadControls`
             for details)
 
         :param bool silent:
@@ -177,7 +177,7 @@ class File(h5py.File):
             :code:`False` (DEFAULT).  Set :code:`True` to ignore any
             UserWarnings (soft-warnings)
 
-        :rtype: :class:`~.hdfreadcontrol.HDFReadControl`
+        :rtype: :class:`~.hdfreadcontrols.HDFReadControls`
 
         :Example:
 
@@ -195,7 +195,7 @@ class File(h5py.File):
             >>> # extract all '6k Compumotor' data for configuration 3
             >>> cdata = f.read_controls([('6K Compumotor', 3)])
             >>> type(cdata)
-            bapsflib._hdf.utils.hdfreadcontrol.HDFReadControl
+            bapsflib._hdf.utils.hdfreadcontrols.HDFReadControls
             >>>
             >>> # list 'Waveform' configurations
             >>> list(f.file_map.controls['Waveform'].configs)
@@ -213,15 +213,15 @@ class File(h5py.File):
             ['6K Compumotor', 'Waveform']
 
         """
-        from .hdfreadcontrol import HDFReadControl
+        from .hdfreadcontrols import HDFReadControls
 
         warn_filter = 'ignore' if silent else 'default'
         with warnings.catch_warnings():
             warnings.simplefilter(warn_filter)
-            data = HDFReadControl(self, controls,
-                                  shotnum=shotnum,
-                                  intersection_set=intersection_set,
-                                  **kwargs)
+            data = HDFReadControls(self, controls,
+                                   shotnum=shotnum,
+                                   intersection_set=intersection_set,
+                                   **kwargs)
 
         return data
 
diff --git a/bapsflib/_hdf/utils/hdfreadcontrol.py b/bapsflib/_hdf/utils/hdfreadcontrols.py
similarity index 98%
rename from bapsflib/_hdf/utils/hdfreadcontrol.py
rename to bapsflib/_hdf/utils/hdfreadcontrols.py
index d817b88..357b7ca 100644
--- a/bapsflib/_hdf/utils/hdfreadcontrol.py
+++ b/bapsflib/_hdf/utils/hdfreadcontrols.py
@@ -31,7 +31,7 @@ ControlsType = Union[str, Iterable[Union[str, Tuple[str, Any]]]]
 IndexDict = Dict[str, np.ndarray]
 
 
-class HDFReadControl(np.ndarray):
+class HDFReadControls(np.ndarray):
     """
     Reads control device data from the HDF5 file.
 
@@ -73,7 +73,7 @@ class HDFReadControl(np.ndarray):
         >>> # read control data
         >>> # - this is equivalent to 
         >>> #   f.read_control(['Waveform', 'config01'])
-        >>> data = HDFReadControl(f, ['Waveform', 'config01'])
+        >>> data = HDFReadControls(f, ['Waveform', 'config01'])
         >>> data.dtype
         dtype([('shotnum', '<u4'), ('command', '<U18')])
         >>>
@@ -548,6 +548,6 @@ class HDFReadControl(np.ndarray):
 
 
 # add example to __new__ docstring
-HDFReadControl.__new__.__doc__ += "\n"
-for line in HDFReadControl.__example_doc__.splitlines():
-    HDFReadControl.__new__.__doc__ += "    " + line + "\n"
+HDFReadControls.__new__.__doc__ += "\n"
+for line in HDFReadControls.__example_doc__.splitlines():
+    HDFReadControls.__new__.__doc__ += "    " + line + "\n"
diff --git a/bapsflib/_hdf/utils/hdfreaddata.py b/bapsflib/_hdf/utils/hdfreaddata.py
index 5987e1e..cd8f0f1 100644
--- a/bapsflib/_hdf/utils/hdfreaddata.py
+++ b/bapsflib/_hdf/utils/hdfreaddata.py
@@ -22,7 +22,7 @@ from warnings import warn
 from .file import File
 from .helpers import (build_sndr_for_simple_dset, condition_controls,
                       condition_shotnum, do_shotnum_intersection)
-from .hdfreadcontrol import HDFReadControl
+from .hdfreadcontrols import HDFReadControls
 
 
 # noinspection PyInitNewSignature
@@ -30,7 +30,7 @@ class HDFReadData(np.ndarray):
     """
     Reads digitizer and control device data from the HDF5 file. Control
     device data is extracted using
-    :class:`~.hdfreadcontrol.HDFReadControl` and combined with the
+    :class:`~.hdfreadcontrols.HDFReadControls` and combined with the
     digitizer data.
 
     This class constructs and returns a structured numpy array.  The
@@ -41,7 +41,7 @@ class HDFReadData(np.ndarray):
     #. control device data which is represented by the remaining fields
        in the numpy array.  These field names are polymorphic and are
        defined by the control device mapping class. (see
-       :class:`~.hdfreadcontrol.HDFReadControl` for more detail)
+       :class:`~.hdfreadcontrols.HDFReadControls` for more detail)
 
     Data that is not shot number specific is stored in the :attr:`info`
     attribute.
@@ -452,10 +452,10 @@ class HDFReadData(np.ndarray):
         # - shotnum should always be a ndarray at this point
         #
         if len(controls) != 0:
-            cdata = HDFReadControl(hdf_file, controls,
-                                   assume_controls_conditioned=True,
-                                   shotnum=shotnum,
-                                   intersection_set=intersection_set)
+            cdata = HDFReadControls(hdf_file, controls,
+                                    assume_controls_conditioned=True,
+                                    shotnum=shotnum,
+                                    intersection_set=intersection_set)
 
             # print execution timing
             if timeit:  # pragma: no cover
diff --git a/bapsflib/_hdf/utils/helpers.py b/bapsflib/_hdf/utils/helpers.py
index 4e103c5..a429ec1 100644
--- a/bapsflib/_hdf/utils/helpers.py
+++ b/bapsflib/_hdf/utils/helpers.py
@@ -36,7 +36,7 @@ def build_shotnum_dset_relation(
     Compares the **shotnum** numpy array to the specified dataset,
     **dset**, to determine which indices contain the desired shot
     number(s)
-    [for :class:`~bapsflib._hdf.utils.hdfreadcontrol.HDFReadControl`].
+    [for :class:`~bapsflib._hdf.utils.hdfreadcontrols.HDFReadControls`].
     As a results, two numpy arrays are returned which satisfy the rule::
 
         shotnum[sni] = dset[index, shotnumkey]
@@ -357,7 +357,7 @@ def condition_controls(hdf_file: File,
                        controls: Any) -> List[Tuple[str, Any]]:
     """
     Conditions the **controls** argument for
-    :class:`~.hdfreadcontrol.HDFReadControl` and
+    :class:`~.hdfreadcontrols.HDFReadControls` and
     :class:`~.hdfreaddata.HDFReadData`.
 
     :param hdf_file: HDF5 object instance
@@ -478,7 +478,7 @@ def condition_shotnum(shotnum: Any,
                       shotnumkey_dict: Dict[str, str]) -> np.ndarray:
     """
     Conditions the **shotnum** argument for
-    :class:`~bapsflib._hdf.utils.hdfreadcontrol.HDFReadControl` and
+    :class:`~bapsflib._hdf.utils.hdfreadcontrols.HDFReadControls` and
     :class:`~bapsflib._hdf.utils.hdfreaddata.HDFReadData`.
 
     :param shotnum: desired HDF5 shot numbers
diff --git a/docs/src/bapsflib._hdf.utils.hdfreadcontrol.rst b/docs/src/bapsflib._hdf.utils.hdfreadcontrol.rst
deleted file mode 100644
index 3ee7d7b..0000000
--- a/docs/src/bapsflib._hdf.utils.hdfreadcontrol.rst
+++ /dev/null
@@ -1,11 +0,0 @@
-bapsflib\.\_hdf\.utils\.hdfreadcontrol
-======================================
-
-.. automodule:: bapsflib._hdf.utils.hdfreadcontrol
-    :members:
-    :undoc-members:
-    :show-inheritance:
-
-    .. rubric:: Classes
-
-    .. autosummary:: HDFReadControl
diff --git a/docs/src/bapsflib._hdf.utils.hdfreadcontrols.rst b/docs/src/bapsflib._hdf.utils.hdfreadcontrols.rst
new file mode 100644
index 0000000..3b36024
--- /dev/null
+++ b/docs/src/bapsflib._hdf.utils.hdfreadcontrols.rst
@@ -0,0 +1,11 @@
+bapsflib\.\_hdf\.utils\.hdfreadcontrols
+=======================================
+
+.. automodule:: bapsflib._hdf.utils.hdfreadcontrols
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
+    .. rubric:: Classes
+
+    .. autosummary:: HDFReadControls
diff --git a/docs/src/bapsflib._hdf.utils.rst b/docs/src/bapsflib._hdf.utils.rst
index addb99d..2fb0e6c 100644
--- a/docs/src/bapsflib._hdf.utils.rst
+++ b/docs/src/bapsflib._hdf.utils.rst
@@ -10,7 +10,7 @@ bapsflib\.\_hdf\.utils
 
     bapsflib._hdf.utils.file
     bapsflib._hdf.utils.hdfoverview
-    bapsflib._hdf.utils.hdfreadcontrol
+    bapsflib._hdf.utils.hdfreadcontrols
     bapsflib._hdf.utils.hdfreaddata
     bapsflib._hdf.utils.hdfreadmsi
     bapsflib._hdf.utils.helpers
diff --git a/docs/using_lapd/file_afteropen.inc.rst b/docs/using_lapd/file_afteropen.inc.rst
index e47b9e4..825e474 100644
--- a/docs/using_lapd/file_afteropen.inc.rst
+++ b/docs/using_lapd/file_afteropen.inc.rst
@@ -68,7 +68,7 @@ attributes for th user to interface with, see :numref:`f_meth_table`.
     :meth:`~File.read_controls`, "
     | high-level method for reading control device data contained in the
       HDF5 file (instance of
-      :class:`~bapsflib._hdf.utils.hdfreadcontrol.HDFReadControl`)
+      :class:`~bapsflib._hdf.utils.hdfreadcontrols.HDFReadControls`)
     | (see :ref:`read_controls` for details)
     "
     :meth:`~File.read_data`, "
diff --git a/docs/using_lapd/read_from_digi.inc.rst b/docs/using_lapd/read_from_digi.inc.rst
index c847c23..e58c529 100644
--- a/docs/using_lapd/read_from_digi.inc.rst
+++ b/docs/using_lapd/read_from_digi.inc.rst
@@ -254,7 +254,7 @@ Adding Control Device Data
 Adding control device data to a digitizer dataset is done with the
 keyword :data:`add_controls`.  Specifying :data:`add_controls` will
 trigger a call to the
-:class:`~bapsflib._hdf.utils.hdfreadcontrol.HDFReadControl` class and
+:class:`~bapsflib._hdf.utils.hdfreadcontrols.HDFReadControls` class and
 extract the desired control device data.
 :class:`~bapsflib._hdf.utils.hdfreaddata.HDFReadData` then compares and
 mates that control device data with the digitizer data according to the
diff --git a/docs/using_lapd/readdata.inc.rst b/docs/using_lapd/readdata.inc.rst
index 8966b81..9712a5a 100644
--- a/docs/using_lapd/readdata.inc.rst
+++ b/docs/using_lapd/readdata.inc.rst
@@ -4,7 +4,7 @@
    method on :class:`bapsflib.lapd.File`:
 
 Three classes :class:`~bapsflib._hdf.utils.hdfreaddata.HDFReadData`,
-:class:`~bapsflib._hdf_utils.hdfreadcontrol.HDFReadControl`, and
+:class:`~bapsflib._hdf_utils.hdfreadcontrols.HDFReadControls`, and
 :class:`~bapsflib._hdf.utils.hdfreadmsi.HDFReadMSI` are given to read
 data for **digitizers**, **control devices**, and **MSI diagnostics**,
 respectively.  Each of these read classes are bound to
@@ -25,7 +25,7 @@ and will return a structured :mod:`numpy` array with the requested data.
     option of mating **control device** data at the time of extraction.
     (see reading :ref:`read_digi`)
     "
-    :class:`~bapsflib._hdf.utils.hdfreadcontrol.HDFReadControl`, "
+    :class:`~bapsflib._hdf.utils.hdfreadcontrols.HDFReadControls`, "
     :meth:`~bapsflib.lapd.File.read_controls`", "
     Designed to extract **control device** data. (see reading
     :ref:`read_controls`)

Refactor `hdfreadcontrol.HDFReadControl` to `hdfreadcontrols.HDFReadControls`
Rename module `hdfreadcontrol.py` and class `HDFReadControl` to `hdfreadcontrols.py` and `HDFReadControls`, respectively.  The plurality better reflects the behavior of the class.  Plus, `HDFReadControl` is bound to `bapsflib._hdf.utils.file.File` as `read_controls()`.
diff --git a/bapsflib/_hdf/maps/controls/tests/common.py b/bapsflib/_hdf/maps/controls/tests/common.py
index 6f6bc19..38c007c 100644
--- a/bapsflib/_hdf/maps/controls/tests/common.py
+++ b/bapsflib/_hdf/maps/controls/tests/common.py
@@ -162,7 +162,7 @@ class ControlTestCase(ut.TestCase):
         #
         # - The `configs` dictionary contains the translation info
         #   in-order to translate the data stored in the HDF5 datasets
-        #   to the structure numpy array constructed by HDFReadControl
+        #   to the structure numpy array constructed by HDFReadControls
         #
         # - Each item in `configs` must be structured as:
         #     Key == name of configuration
@@ -172,7 +172,7 @@ class ControlTestCase(ut.TestCase):
         #   1. translation keys
         #      ('shotnum' and 'state values')
         #
-        #      ~ these keys are used by HDFReadControl and contain the
+        #      ~ these keys are used by HDFReadControls and contain the
         #        the necessary info to translate the data from the HDF5
         #        datasets to the structured numpy array
         #
@@ -180,11 +180,11 @@ class ControlTestCase(ut.TestCase):
         #      ('dset paths')
         #
         #      ~ these keys are used to support the data translation by
-        #        HDFReadControl and are also considered meta-info for
+        #        HDFReadControls and are also considered meta-info for
         #        the Control Device
         #      ~ meta-info keys are added to the `info` dictionary
         #        attribute that is bound to the numpy array data object
-        #        constructed by HDFReadControl
+        #        constructed by HDFReadControls
         #
         #   3. meta-info keys
         #
@@ -192,7 +192,7 @@ class ControlTestCase(ut.TestCase):
         #        for the Control Device
         #      ~ meta-info keys are added to the `info` dictionary
         #        attribute that is bound to the numpy array data object
-        #        constructed by HDFReadControl
+        #        constructed by HDFReadControls
         #
         self.assertIsInstance(_map.configs, dict)
         for config_name, config in _map.configs.items():
diff --git a/bapsflib/_hdf/maps/digitizers/tests/common.py b/bapsflib/_hdf/maps/digitizers/tests/common.py
index f7f28d7..410063d 100644
--- a/bapsflib/_hdf/maps/digitizers/tests/common.py
+++ b/bapsflib/_hdf/maps/digitizers/tests/common.py
@@ -169,7 +169,7 @@ class DigitizerTestCase(ut.TestCase):
         #        for the Digitizer
         #      ~ meta-info keys are added to the `info` dictionary
         #        attribute that is bound to the numpy array data object
-        #        constructed by HDFReadControl
+        #        constructed by HDFReadControls
         #
         self.assertIsInstance(_map.configs, dict)
         for cname, config in _map.configs.items():
diff --git a/bapsflib/_hdf/utils/tests/test_file.py b/bapsflib/_hdf/utils/tests/test_file.py
index 1ddc059..41be689 100644
--- a/bapsflib/_hdf/utils/tests/test_file.py
+++ b/bapsflib/_hdf/utils/tests/test_file.py
@@ -21,7 +21,7 @@ from unittest import mock
 from . import (TestBase, with_bf)
 from ..file import File
 from ..hdfoverview import HDFOverview
-from ..hdfreadcontrol import HDFReadControl
+from ..hdfreadcontrols import HDFReadControls
 from ..hdfreaddata import HDFReadData
 from ..hdfreadmsi import HDFReadMSI
 
@@ -100,8 +100,8 @@ class TestFile(TestBase):
 
         # calling `read_controls`
         with mock.patch(
-                HDFReadControl.__module__ + '.'
-                + HDFReadControl.__qualname__,
+                HDFReadControls.__module__ + '.'
+                + HDFReadControls.__qualname__,
                 return_value='read control') as mock_rc:
             extras = {
                 'shotnum': 2,
diff --git a/bapsflib/_hdf/utils/tests/test_hdfreadcontrol.py b/bapsflib/_hdf/utils/tests/test_hdfreadcontrol.py
index 33034a8..ec1bdb9 100644
--- a/bapsflib/_hdf/utils/tests/test_hdfreadcontrol.py
+++ b/bapsflib/_hdf/utils/tests/test_hdfreadcontrol.py
@@ -22,21 +22,21 @@ from unittest import mock
 
 from . import (TestBase, with_bf)
 from ..file import File
-from ..hdfreadcontrol import HDFReadControl
+from ..hdfreadcontrols import HDFReadControls
 
 
 class TestHDFReadControl(TestBase):
-    """Test Case for HDFReadControl class."""
+    """Test Case for HDFReadControls class."""
     # Note:
-    # - Key code segments of HDFReadControl are tested by:
+    # - Key code segments of HDFReadControls are tested by:
     #   1. TestConditionControls
     #   2. TestConditionShotnum
     #   3. TestBuildShotnumDsetRelation
     #   4. TestDoShotnumIntersection
-    # - TestBuildShotnumDsetRelation tests HDFReadControl's ability to
+    # - TestBuildShotnumDsetRelation tests HDFReadControls's ability to
     #   properly identify the dataset indices corresponding to the
     #   desired shot numbers (it checks against an original dataset)
-    # - TestDoIntersection tests HDFReadControl's ability to intersect
+    # - TestDoIntersection tests HDFReadControls's ability to intersect
     #   all shot numbers between the datasets and shotnum
     # - Thus, testing here should focus on the construction and
     #   basic population of cdata and not so much ensuring the exact
@@ -77,10 +77,10 @@ class TestHDFReadControl(TestBase):
         #   condition_shotnum() and TestConditionShotnum
         #
         # `hdf_fil` is NOT a bapsflib._hdf.utils.file.File
-        self.assertRaises(TypeError, HDFReadControl, self.f, [])
+        self.assertRaises(TypeError, HDFReadControls, self.f, [])
 
         # HDF5 file object has no mapped control devices
-        self.assertRaises(ValueError, HDFReadControl, _bf, [])
+        self.assertRaises(ValueError, HDFReadControls, _bf, [])
 
     @with_bf
     def test_misc_behavior(self, _bf: File):
@@ -97,8 +97,8 @@ class TestHDFReadControl(TestBase):
                          {'sn_requested': sn,
                           'sn_correct': sn,
                           'sn_valid': sn})]
-        data = HDFReadControl(_bf, controls, shotnum=sn,
-                              assume_controls_conditioned=False)
+        data = HDFReadControls(_bf, controls, shotnum=sn,
+                               assume_controls_conditioned=False)
         self.assertCDataObj(data, _bf, control_plus)
 
     @with_bf
@@ -208,9 +208,9 @@ class TestHDFReadControl(TestBase):
         sn = np.array([8, 9, 10, 11, 12, 13], dtype=np.uint32)
         sn_v = np.array([8, 9, 10], dtype=np.uint32)
         controls = [('Sample', 'config01')]
-        cdata = HDFReadControl(_bf, controls,
-                               shotnum=sn,
-                               assume_controls_conditioned=True)
+        cdata = HDFReadControls(_bf, controls,
+                                shotnum=sn,
+                                assume_controls_conditioned=True)
         self.assertTrue(np.array_equal(cdata['shotnum'], sn_v))
         self.assertTrue(np.array_equal(
             cdata['xyz'][..., 1],
@@ -243,9 +243,9 @@ class TestHDFReadControl(TestBase):
         sn_v = np.array([8, 9, 10], dtype=np.uint32)
         controls = [('Sample', 'config01')]
         with self.assertWarns(UserWarning):
-            cdata = HDFReadControl(_bf, controls,
-                                   shotnum=sn,
-                                   assume_controls_conditioned=True)
+            cdata = HDFReadControls(_bf, controls,
+                                    shotnum=sn,
+                                    assume_controls_conditioned=True)
 
             self.assertTrue(np.array_equal(cdata['shotnum'], sn_v))
             self.assertTrue(np.all(np.isnan(cdata['xyz'][..., 0])))
@@ -284,9 +284,9 @@ class TestHDFReadControl(TestBase):
         sn = np.array([8, 9, 10, 11, 12, 13], dtype=np.uint32)
         controls = [('Sample', 'config01')]
         with self.assertRaises(ValueError):
-            cdata = HDFReadControl(_bf, controls,
-                                   shotnum=sn,
-                                   assume_controls_conditioned=True)
+            cdata = HDFReadControls(_bf, controls,
+                                    shotnum=sn,
+                                    assume_controls_conditioned=True)
 
     @with_bf
     @mock.patch.object(HDFMap, 'controls',
@@ -391,11 +391,11 @@ class TestHDFReadControl(TestBase):
                              {'sn_requested': sn,
                               'sn_correct': sn,
                               'sn_valid': sn_v})]
-            data = HDFReadControl(_bf,
-                                  controls,
-                                  shotnum=sn,
-                                  intersection_set=False,
-                                  assume_controls_conditioned=True)
+            data = HDFReadControls(_bf,
+                                   controls,
+                                   shotnum=sn,
+                                   intersection_set=False,
+                                   assume_controls_conditioned=True)
             self.assertCDataObj(data, _bf, control_plus,
                                 intersection_set=False)
 
@@ -464,7 +464,7 @@ class TestHDFReadControl(TestBase):
             control_plus[0][2]['sn_valid'] = sn_v
 
             # grab requested control data
-            cdata = HDFReadControl(_bf, control, shotnum=sn_r)
+            cdata = HDFReadControls(_bf, control, shotnum=sn_r)
 
             # assert cdata format
             self.assertCDataObj(cdata, _bf, control_plus)
@@ -501,9 +501,9 @@ class TestHDFReadControl(TestBase):
             control_plus[0][2]['sn_valid'] = sn_v
 
             # grab requested control data
-            cdata = HDFReadControl(_bf, control,
-                                   shotnum=sn_r,
-                                   intersection_set=False)
+            cdata = HDFReadControls(_bf, control,
+                                    shotnum=sn_r,
+                                    intersection_set=False)
             # assert cdata format
             self.assertCDataObj(cdata, _bf, control_plus,
                                 intersection_set=False)
@@ -517,12 +517,12 @@ class TestHDFReadControl(TestBase):
         control_plus[0][2]['sn_valid'] = sn_c
 
         # grab & test data for intersection_set=True
-        cdata = HDFReadControl(_bf, control)
+        cdata = HDFReadControls(_bf, control)
         self.assertCDataObj(cdata, _bf, control_plus)
 
         # grab & test data for intersection_set=False
-        cdata = HDFReadControl(_bf, control,
-                               intersection_set=False)
+        cdata = HDFReadControls(_bf, control,
+                                intersection_set=False)
         self.assertCDataObj(cdata, _bf, control_plus,
                             intersection_set=False)
 
@@ -531,7 +531,7 @@ class TestHDFReadControl(TestBase):
         dset_name = self.f.modules['6K Compumotor']._configs[
             sixk_cspec]['dset name']
         dset = self.f.modules['6K Compumotor'][dset_name]
-        sn_arr = dset['Shot number']
+        sn_arr = dset['Shot number']  # type: np.ndarray
         sn_arr[30::] = np.arange(41, 61, 1, dtype=sn_arr.dtype)
         dset['Shot number'] = sn_arr
         _bf._map_file()  # re-map file
@@ -562,7 +562,7 @@ class TestHDFReadControl(TestBase):
             control_plus[0][2]['sn_valid'] = sn_v
 
             # grab requested control data
-            cdata = HDFReadControl(_bf, control, shotnum=sn_r)
+            cdata = HDFReadControls(_bf, control, shotnum=sn_r)
 
             # assert cdata format
             self.assertCDataObj(cdata, _bf, control_plus)
@@ -599,9 +599,9 @@ class TestHDFReadControl(TestBase):
             control_plus[0][2]['sn_valid'] = sn_v
 
             # grab requested control data
-            cdata = HDFReadControl(_bf, control,
-                                   shotnum=sn_r,
-                                   intersection_set=False)
+            cdata = HDFReadControls(_bf, control,
+                                    shotnum=sn_r,
+                                    intersection_set=False)
 
             # assert cdata format
             self.assertCDataObj(cdata, _bf, control_plus,
@@ -616,13 +616,13 @@ class TestHDFReadControl(TestBase):
         control_plus[0][2]['sn_valid'] = sn_c
 
         # grab & test data for intersection_set=True
-        cdata = HDFReadControl(_bf, control)
+        cdata = HDFReadControls(_bf, control)
         self.assertCDataObj(cdata, _bf, control_plus)
 
         # grab & test data for intersection_set=False
         sn_c = np.arange(1, 61, 1)
         control_plus[0][2]['sn_correct'] = sn_c
-        cdata = HDFReadControl(_bf, control, intersection_set=False)
+        cdata = HDFReadControls(_bf, control, intersection_set=False)
         self.assertCDataObj(cdata, _bf, control_plus,
                             intersection_set=False)
 
@@ -706,7 +706,7 @@ class TestHDFReadControl(TestBase):
             control_plus[1][2]['sn_valid'] = sn_sk
 
             # grab requested control data
-            cdata = HDFReadControl(_bf, control, shotnum=sn_r)
+            cdata = HDFReadControls(_bf, control, shotnum=sn_r)
 
             # assert cdata format
             self.assertCDataObj(cdata, _bf, control_plus)
@@ -751,8 +751,8 @@ class TestHDFReadControl(TestBase):
             control_plus[1][2]['sn_valid'] = sn_sk
 
             # grab requested control data
-            cdata = HDFReadControl(_bf, control, shotnum=sn_r,
-                                   intersection_set=False)
+            cdata = HDFReadControls(_bf, control, shotnum=sn_r,
+                                    intersection_set=False)
 
             # assert cdata format
             self.assertCDataObj(cdata, _bf, control_plus,
@@ -774,12 +774,12 @@ class TestHDFReadControl(TestBase):
         control_plus[1][2]['sn_valid'] = sn_c
 
         # grab & test data for intersection_set=True
-        cdata = HDFReadControl(_bf, control)
+        cdata = HDFReadControls(_bf, control)
         self.assertCDataObj(cdata, _bf, control_plus)
 
         # grab & test data for intersection_set=False
-        cdata = HDFReadControl(_bf, control,
-                               intersection_set=False)
+        cdata = HDFReadControls(_bf, control,
+                                intersection_set=False)
         self.assertCDataObj(cdata, _bf, control_plus,
                             intersection_set=False)
 
@@ -791,7 +791,7 @@ class TestHDFReadControl(TestBase):
         dset_name = self.f.modules['Waveform']._configs[
             'config01']['dset name']
         dset = self.f.modules['Waveform'][dset_name]
-        sn_arr = dset['Shot number']
+        sn_arr = dset['Shot number']  # type: np.ndarray
         sn_arr[20::] = np.arange(31, 61, 1, dtype=sn_arr.dtype)
         dset['Shot number'] = sn_arr
         sn_wave = sn_arr
@@ -800,7 +800,7 @@ class TestHDFReadControl(TestBase):
         dset_name = self.f.modules['6K Compumotor']._configs[
             sixk_cspec]['dset name']
         dset = self.f.modules['6K Compumotor'][dset_name]
-        sn_arr = dset['Shot number']
+        sn_arr = dset['Shot number']  # type: np.ndarray
         sn_arr[30::] = np.arange(38, 58, 1, dtype=sn_arr.dtype)
         dset['Shot number'] = sn_arr
         sn_sixk = sn_arr
@@ -840,7 +840,7 @@ class TestHDFReadControl(TestBase):
             control_plus[1][2]['sn_valid'] = sn_sk
 
             # grab requested control data
-            cdata = HDFReadControl(_bf, control, shotnum=sn_r)
+            cdata = HDFReadControls(_bf, control, shotnum=sn_r)
 
             # assert cdata format
             self.assertCDataObj(cdata, _bf, control_plus)
@@ -891,8 +891,8 @@ class TestHDFReadControl(TestBase):
             control_plus[1][2]['sn_valid'] = sn_sk
 
             # grab requested control data
-            cdata = HDFReadControl(_bf, control, shotnum=sn_r,
-                                   intersection_set=False)
+            cdata = HDFReadControls(_bf, control, shotnum=sn_r,
+                                    intersection_set=False)
 
             # assert cdata format
             self.assertCDataObj(cdata, _bf, control_plus,
@@ -914,7 +914,7 @@ class TestHDFReadControl(TestBase):
         control_plus[1][2]['sn_valid'] = sn_c
 
         # grab & test data for intersection_set=True
-        cdata = HDFReadControl(_bf, control)
+        cdata = HDFReadControls(_bf, control)
         self.assertCDataObj(cdata, _bf, control_plus)
 
         # grab & test data for intersection_set=False
@@ -926,19 +926,19 @@ class TestHDFReadControl(TestBase):
         control_plus[1][2]['sn_valid'] = \
             np.intersect1d(sn_c, sn_sixk)  # type: np.ndarray
 
-        cdata = HDFReadControl(_bf, control,
-                               intersection_set=False)
+        cdata = HDFReadControls(_bf, control,
+                                intersection_set=False)
         self.assertCDataObj(cdata, _bf, control_plus,
                             intersection_set=False)
 
     def assertCDataObj(
             self,
-            cdata: HDFReadControl,
+            cdata: HDFReadControls,
             _bf: File,
             control_plus: List[Tuple[str, Any, Dict[str, Any]]],
             intersection_set=True):
         """Assertion for detailed format of returned data object."""
-        # cdata            - returned data object of HDFReadControl()
+        # cdata            - returned data object of HDFReadControls()
         # control_plus     - control name, control configuration, and
         #                    expected shot numbers ('sn_valid')
         # intersection_set - whether cdata is generated w/
@@ -952,13 +952,13 @@ class TestHDFReadControl(TestBase):
         self.assertTrue(hasattr(cdata, 'info'))
         self.assertIsInstance(cdata.info, dict)
 
-        # examine HDFReadControl defined keys
+        # examine HDFReadControls defined keys
         self.assertIn('source file', cdata.info)
         self.assertIn('controls', cdata.info)
         self.assertIn('probe name', cdata.info)
         self.assertIn('port', cdata.info)
 
-        # examine values of HDFReadControl defined keys
+        # examine values of HDFReadControls defined keys
         self.assertEqual(cdata.info['source file'],
                          os.path.abspath(_bf.filename))
         self.assertIsInstance(cdata.info['controls'], dict)
diff --git a/bapsflib/_hdf/utils/tests/test_hdfreaddata.py b/bapsflib/_hdf/utils/tests/test_hdfreaddata.py
index 6bf8f33..bf79980 100644
--- a/bapsflib/_hdf/utils/tests/test_hdfreaddata.py
+++ b/bapsflib/_hdf/utils/tests/test_hdfreaddata.py
@@ -23,7 +23,7 @@ from unittest import mock
 
 from . import (TestBase, with_bf)
 from ..file import File
-from ..hdfreadcontrol import HDFReadControl
+from ..hdfreadcontrols import HDFReadControls
 from ..hdfreaddata import (build_sndr_for_simple_dset,
                            condition_shotnum,
                            do_shotnum_intersection,
@@ -46,7 +46,7 @@ class TestHDFReadData(TestBase):
         super().tearDown()
 
     @with_bf
-    @mock.patch('bapsflib._hdf.utils.hdfreaddata.HDFReadControl')
+    @mock.patch('bapsflib._hdf.utils.hdfreaddata.HDFReadControls')
     @mock.patch('bapsflib._hdf.utils.hdfreaddata.condition_controls')
     @mock.patch.object(HDFMap, 'controls',
                        new_callable=mock.PropertyMock,
@@ -102,9 +102,9 @@ class TestHDFReadData(TestBase):
                 }
             }
         }
-        m_cdata = np.reshape(cdata[4], 1).view(HDFReadControl)
+        m_cdata = np.reshape(cdata[4], 1).view(HDFReadControls)
         m_cdata._info = m_info
-        mock_cdata.return_value = m_cdata.view(HDFReadControl)
+        mock_cdata.return_value = m_cdata.view(HDFReadControls)
         data = HDFReadData(_bf, brd, ch, config_name=config_name,
                            adc=adc, digitizer=digi, shotnum=shotnum,
                            add_controls=[('control', 'config01')],
@@ -136,9 +136,9 @@ class TestHDFReadData(TestBase):
         fields = list(cdata.dtype.names)
         fields.remove('xyz')
         m_cdata = np.reshape(cdata[fields][4], (1,))
-        m_cdata = m_cdata.view(HDFReadControl)
+        m_cdata = m_cdata.view(HDFReadControls)
         m_cdata._info = m_info
-        mock_cdata.return_value = m_cdata.view(HDFReadControl)
+        mock_cdata.return_value = m_cdata.view(HDFReadControls)
         data = HDFReadData(_bf, brd, ch, config_name=config_name,
                            adc=adc, digitizer=digi, shotnum=shotnum,
                            add_controls=[('control', 'config01')],
@@ -167,9 +167,9 @@ class TestHDFReadData(TestBase):
                 }
             }
         }
-        m_cdata = np.reshape(cdata[4], 1).view(HDFReadControl)
+        m_cdata = np.reshape(cdata[4], 1).view(HDFReadControls)
         m_cdata._info = m_info
-        mock_cdata.return_value = m_cdata.view(HDFReadControl)
+        mock_cdata.return_value = m_cdata.view(HDFReadControls)
         data = HDFReadData(_bf, brd, ch, config_name=config_name,
                            adc=adc, digitizer=digi, shotnum=shotnum,
                            add_controls=[('control', 'config01')],
@@ -199,14 +199,14 @@ class TestHDFReadData(TestBase):
                 }
             }
         }
-        m_cdata = np.empty(1, dtype=cdata.dtype).view(HDFReadControl)
+        m_cdata = np.empty(1, dtype=cdata.dtype).view(HDFReadControls)
         m_cdata[0]['shotnum'] = 20
         m_cdata[0]['xyz'] = np.nan
         m_cdata[0]['freq'] = np.nan
         m_cdata = np.append(m_cdata, np.reshape(cdata[4], 1))
-        m_cdata = m_cdata.view(HDFReadControl)
+        m_cdata = m_cdata.view(HDFReadControls)
         m_cdata._info = m_info
-        mock_cdata.return_value = m_cdata.view(HDFReadControl)
+        mock_cdata.return_value = m_cdata.view(HDFReadControls)
         data = HDFReadData(_bf, brd, ch, config_name=config_name,
                            adc=adc, digitizer=digi, shotnum=shotnum,
                            add_controls=[('control', 'config01')],
@@ -971,7 +971,7 @@ class TestHDFReadData(TestBase):
         mock_inter.reset_mock()
 
     def assertControlInData(self,
-                            cdata: HDFReadControl,
+                            cdata: HDFReadControls,
                             data: HDFReadData,
                             shotnum: np.ndarray):
 

pip install -e .
parse_log_pytest
requirements.txt
pytest
3.7
requirements.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
alabaster==0.7.13
astropy==4.3.1
Babel==2.14.0
-e git+https://github.com/BaPSF/bapsflib.git@6a79d1eff5c7c46a236410c57e7298613485fec1#egg=bapsflib
certifi @ file:///croot/certifi_1671487769961/work/certifi
charset-normalizer==3.4.1
codecov==2.1.13
coverage==7.2.7
docutils==0.19
exceptiongroup==1.2.2
h5py==3.8.0
idna==3.10
imagesize==1.4.1
importlib-metadata==6.7.0
iniconfig==2.0.0
Jinja2==3.1.6
MarkupSafe==2.1.5
numpy==1.21.6
packaging==24.0
pluggy==1.2.0
pyerfa==2.0.0.3
Pygments==2.17.2
pytest==7.4.4
pytz==2025.2
requests==2.31.0
scipy==1.7.3
snowballstemmer==2.2.0
Sphinx==5.3.0
sphinx-rtd-theme==2.0.0
sphinxcontrib-applehelp==1.0.2
sphinxcontrib-devhelp==1.0.2
sphinxcontrib-htmlhelp==2.0.0
sphinxcontrib-jquery==4.1
sphinxcontrib-jsmath==1.0.1
sphinxcontrib-qthelp==1.0.3
sphinxcontrib-serializinghtml==1.1.5
tomli==2.0.1
typing_extensions==4.7.1
urllib3==2.0.7
zipp==3.15.0

name: bapsflib
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - certifi=2022.12.7=py37h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=1.1.1w=h7f8727e_0
  - pip=22.3.1=py37h06a4308_0
  - python=3.7.16=h7a1cb2a_0
  - readline=8.2=h5eee18b_0
  - setuptools=65.6.3=py37h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - wheel=0.38.4=py37h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - alabaster==0.7.13
      - astropy==4.3.1
      - babel==2.14.0
      - charset-normalizer==3.4.1
      - codecov==2.1.13
      - coverage==7.2.7
      - docutils==0.19
      - exceptiongroup==1.2.2
      - h5py==3.8.0
      - idna==3.10
      - imagesize==1.4.1
      - importlib-metadata==6.7.0
      - iniconfig==2.0.0
      - jinja2==3.1.6
      - markupsafe==2.1.5
      - numpy==1.21.6
      - packaging==24.0
      - pluggy==1.2.0
      - pyerfa==2.0.0.3
      - pygments==2.17.2
      - pytest==7.4.4
      - pytz==2025.2
      - requests==2.31.0
      - scipy==1.7.3
      - snowballstemmer==2.2.0
      - sphinx==5.3.0
      - sphinx-rtd-theme==2.0.0
      - sphinxcontrib-applehelp==1.0.2
      - sphinxcontrib-devhelp==1.0.2
      - sphinxcontrib-htmlhelp==2.0.0
      - sphinxcontrib-jquery==4.1
      - sphinxcontrib-jsmath==1.0.1
      - sphinxcontrib-qthelp==1.0.3
      - sphinxcontrib-serializinghtml==1.1.5
      - tomli==2.0.1
      - typing-extensions==4.7.1
      - urllib3==2.0.7
      - zipp==3.15.0
prefix: /opt/conda/envs/bapsflib

bapsflib/_hdf/utils/tests/test_file.py::TestFile::test_file bapsflib/_hdf/utils/tests/test_hdfreadcontrol.py::TestHDFReadControl::test_raise_errors bapsflib/_hdf/utils/tests/test_hdfreaddata.py::TestHDFReadData::test_kwarg_adc bapsflib/_hdf/utils/tests/test_hdfreaddata.py::TestHDFReadData::test_kwarg_board bapsflib/_hdf/utils/tests/test_hdfreaddata.py::TestHDFReadData::test_kwarg_channel bapsflib/_hdf/utils/tests/test_hdfreaddata.py::TestHDFReadData::test_kwarg_config_name bapsflib/_hdf/utils/tests/test_hdfreaddata.py::TestHDFReadData::test_kwarg_digitizer bapsflib/_hdf/utils/tests/test_hdfreaddata.py::TestHDFReadData::test_misc_behavior bapsflib/_hdf/utils/tests/test_hdfreaddata.py::TestHDFReadData::test_raise_errors
bapsflib/_hdf/utils/tests/test_hdfreadcontrol.py::TestHDFReadControl::test_misc_behavior bapsflib/_hdf/utils/tests/test_hdfreadcontrol.py::TestHDFReadControl::test_missing_dataset_fields bapsflib/_hdf/utils/tests/test_hdfreadcontrol.py::TestHDFReadControl::test_nan_fill bapsflib/_hdf/utils/tests/test_hdfreadcontrol.py::TestHDFReadControl::test_single_control bapsflib/_hdf/utils/tests/test_hdfreadcontrol.py::TestHDFReadControl::test_two_controls bapsflib/_hdf/utils/tests/test_hdfreaddata.py::TestHDFReadData::test_adding_controls bapsflib/_hdf/utils/tests/test_hdfreaddata.py::TestHDFReadData::test_kwarg_intersection_set bapsflib/_hdf/utils/tests/test_hdfreaddata.py::TestHDFReadData::test_kwarg_keep_bits bapsflib/_hdf/utils/tests/test_hdfreaddata.py::TestHDFReadData::test_read_w_index bapsflib/_hdf/utils/tests/test_hdfreaddata.py::TestHDFReadData::test_read_w_shotnum
bapsflib/_hdf/utils/hdfreaddata.py bapsflib/_hdf/utils/hdfreadcontrol.py bapsflib/_hdf/utils/helpers.py bapsflib/_hdf/maps/controls/templates.py docs/using_lapd/file_afteropen.inc.rst bapsflib/_hdf/utils/__init__.py docs/using_lapd/read_from_digi.inc.rst bapsflib/_hdf/maps/controls/sixk.py docs/src/bapsflib._hdf.utils.rst docs/using_lapd/readdata.inc.rst docs/src/bapsflib._hdf.utils.hdfreadcontrol.rst bapsflib/_hdf/utils/file.py docs/src/bapsflib._hdf.utils.hdfreadcontrols.rst
bapsflib/_hdf/utils/hdfreaddata.py bapsflib/_hdf/utils/helpers.py bapsflib/_hdf/maps/controls/templates.py docs/using_lapd/file_afteropen.inc.rst bapsflib/_hdf/utils/__init__.py docs/using_lapd/read_from_digi.inc.rst bapsflib/_hdf/maps/controls/sixk.py docs/src/bapsflib._hdf.utils.rst bapsflib/_hdf/utils/hdfreadcontrols.py docs/using_lapd/readdata.inc.rst docs/src/bapsflib._hdf.utils.hdfreadcontrol.rst bapsflib/_hdf/utils/file.py docs/src/bapsflib._hdf.utils.hdfreadcontrols.rst