diff --git a/becquerel/core/spectrum.py b/becquerel/core/spectrum.py
index b638b9b..88e9398 100644
--- a/becquerel/core/spectrum.py
+++ b/becquerel/core/spectrum.py
@@ -948,7 +948,7 @@ class Spectrum(object):
         return True
 
     def find_bin_index(self, x, use_kev=True):
-        """Find the Spectrum bin index that contains an x-axis value x.
+        """Find the Spectrum bin index or indices containing x-axis value(s) x.
 
         If the Spectrum has uniform binning, then we just solve the linear
         equation between bin indices and x-axis values. Otherwise, we use
@@ -956,15 +956,15 @@ class Spectrum(object):
         list of bin edges, then subtract 1 to get the index of the low edge.
 
         Args:
-          x: value whose bin to find
+          x: value(s) whose bin to find
           use_kev: check bin_edges_kev if True, otherwise bin_edges_raw
 
         Raises:
-          AssertionError: if x is outside the bin edges or equal to up edge
-          SpectrumError: if use_kev=True but Spectrum is not calibrated
+          SpectrumError: if use_kev=True but Spectrum is not calibrated; or if
+            x is outside the bin edges or equal to up edge
 
         Returns:
-          The integer bin index that contains x
+          The integer bin index or indices containing x
         """
 
         if use_kev and not self.is_calibrated:
@@ -973,12 +973,15 @@ class Spectrum(object):
 
         bin_edges = self.bin_edges_kev if use_kev else self.bin_edges_raw
         bin_widths = self.bin_widths_kev if use_kev else self.bin_widths_raw
+        x = np.asarray(x)
 
-        assert x >= bin_edges[0]
-        assert x < bin_edges[-1]
+        if np.any(x < bin_edges[0]):
+            raise SpectrumError('requested x is < lowest bin edge')
+        if np.any(x >= bin_edges[-1]):
+            raise SpectrumError('requested x is >= highest bin edge')
 
         if self.has_uniform_bins(use_kev=use_kev):
-            return int((x - bin_edges[0]) / bin_widths[0])
+            return ((x - bin_edges[0]) / bin_widths[0]).astype(np.int)
         else:
             return np.searchsorted(bin_edges, x, 'right') - 1
 
diff --git a/examples/spectrum.ipynb b/examples/spectrum.ipynb
index 268015a..b559f82 100644
--- a/examples/spectrum.ipynb
+++ b/examples/spectrum.ipynb
@@ -11,22 +11,13 @@
    "cell_type": "code",
    "execution_count": 1,
    "metadata": {},
-   "outputs": [
-    {
-     "name": "stderr",
-     "output_type": "stream",
-     "text": [
-      "becquerel/tools/xcom.py:13: DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated, and in 3.8 it will stop working\n",
-      "  from collections import Iterable\n"
-     ]
-    }
-   ],
+   "outputs": [],
    "source": [
     "# Reload\n",
     "%load_ext autoreload\n",
     "%autoreload 2\n",
     "\n",
-    "from becquerel import Spectrum\n",
+    "from becquerel import Spectrum, SpectrumError\n",
     "import numpy as np\n",
     "np.random.seed(0)"
    ]
@@ -442,7 +433,7 @@
      "name": "stderr",
      "output_type": "stream",
      "text": [
-      "becquerel/core/spectrum.py:724: SpectrumWarning: Subtraction of counts-based specta, spectra have been converted to CPS\n",
+      "becquerel/core/spectrum.py:726: SpectrumWarning: Subtraction of counts-based specta, spectra have been converted to CPS\n",
       "  'have been converted to CPS', SpectrumWarning)\n"
      ]
     },
@@ -656,8 +647,7 @@
     "plt.plot(spec7.bin_edges_raw[:-1], spec7.counts_vals)\n",
     "plt.show()\n",
     "# Note that the Spectrum.plot() method fails here because it works in bin mode.\n",
-    "# There might be a kwargs solution to that problem, but it should be fixed later.\n",
-    "# Note also that we still call bin_edges_kev, because bin_edges_adc has not yet been implemented."
+    "# There might be a kwargs solution to that problem, but it should be fixed later."
    ]
   },
   {
@@ -727,7 +717,7 @@
    "cell_type": "markdown",
    "metadata": {},
    "source": [
-    "Find the bins corresponding to a particular channel"
+    "Find the bins corresponding to a particular channel(s)"
    ]
   },
   {
@@ -741,14 +731,18 @@
      "text": [
       "399\n",
       "0\n",
-      "999\n"
+      "999\n",
+      "[400 500 600]\n",
+      "[  1  58 105]\n"
      ]
     }
    ],
    "source": [
     "print(spec7.find_bin_index(3996, use_kev=False))\n",
     "print(spec7.find_bin_index(0, use_kev=False))\n",
-    "print(spec7.find_bin_index(9999, use_kev=False))"
+    "print(spec7.find_bin_index(9999, use_kev=False))\n",
+    "print(spec7.find_bin_index(np.array([4000, 5000, 6000]), use_kev=False))\n",
+    "print(spec8.find_bin_index(np.array([4000, 5000, 6000]), use_kev=False))"
    ]
   },
   {
@@ -768,7 +762,7 @@
     "# test that the bin up edge is out-of-range\n",
     "try:\n",
     "    print(spec7.find_bin_index(10000, use_kev=False))\n",
-    "except AssertionError:\n",
+    "except SpectrumError:\n",
     "    print(\"Failed successfully!\")"
    ]
   },

Spectrum `find_bin_index` should be able to accept multiple x-values
Spectrum `find_bin_index` should be able to accept multiple x-values and return their bin indices. This should be pretty simple to implement.
diff --git a/tests/spectrum_test.py b/tests/spectrum_test.py
index aee9e98..aafe678 100644
--- a/tests/spectrum_test.py
+++ b/tests/spectrum_test.py
@@ -253,9 +253,13 @@ def test_listmode():
     assert spec0.find_bin_index(XMIN, use_kev=False) == 0
     assert spec0.find_bin_index(XMIN + BW/4.0, use_kev=False) == 0
     assert spec0.find_bin_index(XMAX - BW/4.0, use_kev=False) == NBINS - 1
-    with pytest.raises(AssertionError):
+    assert np.all(spec0.find_bin_index(
+        spec0.bin_edges_raw[:-1], use_kev=False) == np.arange(NBINS))
+
+    # raise errors
+    with pytest.raises(bq.SpectrumError):
         spec0.find_bin_index(XMAX, use_kev=False)
-    with pytest.raises(AssertionError):
+    with pytest.raises(bq.SpectrumError):
         spec0.find_bin_index(XMIN - BW/4.0, use_kev=False)
 
     # test without args
@@ -271,6 +275,14 @@ def test_listmode():
     assert spec2.find_bin_index(1e1, use_kev=False) == 0
     assert spec2.find_bin_index(1e1 + 1e-9, use_kev=False) == 0
     assert spec2.find_bin_index(1e4 - 1e-9, use_kev=False) == NBINS - 1
+    assert np.all(spec2.find_bin_index(
+        spec2.bin_edges_raw[:-1], use_kev=False) == np.arange(NBINS))
+
+    # additional type checking
+    assert isinstance(
+        spec0.find_bin_index(XMIN, use_kev=False), (int, np.integer))
+    assert isinstance(
+        spec0.find_bin_index([XMIN], use_kev=False), np.ndarray)
 
 
 # ----------------------------------------------

pip install -e .[dev]
parse_log_pytest
requirements.txt
pytest pytest-cov
apt-get update apt-get install -y gcc
3.6
requirements.txt requirements-dev.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
astroid==2.11.7
attrs==22.2.0
beautifulsoup4==4.12.3
-e git+https://github.com/lbl-anp/becquerel.git@3e56c2465c48f1a712d1788ddd31a8355d97264e#egg=becquerel
certifi==2021.5.30
charset-normalizer==2.0.12
coverage==6.2
cycler==0.11.0
dill==0.3.4
flake8==5.0.4
future==1.0.0
html5lib==1.1
idna==3.10
importlib-metadata==4.2.0
iniconfig==1.1.1
isort==5.10.1
kiwisolver==1.3.1
lazy-object-proxy==1.7.1
llvmlite==0.36.0
lxml==5.3.1
matplotlib==3.3.4
mccabe==0.7.0
numba==0.53.1
numpy==1.19.5
packaging==21.3
pandas==1.1.5
Pillow==8.4.0
platformdirs==2.4.0
pluggy==1.0.0
py==1.11.0
pycodestyle==2.9.1
pydocstyle==6.3.0
pyflakes==2.5.0
pylint==2.13.9
pyparsing==3.1.4
pytest==7.0.1
pytest-cov==4.0.0
python-dateutil==2.9.0.post0
pytz==2025.2
requests==2.27.1
scipy==1.5.4
six==1.17.0
snowballstemmer==2.2.0
soupsieve==2.3.2.post1
tomli==1.2.3
typed-ast==1.5.5
typing_extensions==4.1.1
uncertainties==3.1.7
urllib3==1.26.20
webencodings==0.5.1
wrapt==1.16.0
zipp==3.6.0

name: becquerel
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=2021.5.30=py36h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.3=he6710b0_2
  - 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=21.2.2=py36h06a4308_0
  - python=3.6.13=h12debd9_1
  - readline=8.2=h5eee18b_0
  - setuptools=58.0.4=py36h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - wheel=0.37.1=pyhd3eb1b0_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - astroid==2.11.7
      - attrs==22.2.0
      - beautifulsoup4==4.12.3
      - charset-normalizer==2.0.12
      - coverage==6.2
      - cycler==0.11.0
      - dill==0.3.4
      - flake8==5.0.4
      - future==1.0.0
      - html5lib==1.1
      - idna==3.10
      - importlib-metadata==4.2.0
      - iniconfig==1.1.1
      - isort==5.10.1
      - kiwisolver==1.3.1
      - lazy-object-proxy==1.7.1
      - llvmlite==0.36.0
      - lxml==5.3.1
      - matplotlib==3.3.4
      - mccabe==0.7.0
      - numba==0.53.1
      - numpy==1.19.5
      - packaging==21.3
      - pandas==1.1.5
      - pillow==8.4.0
      - platformdirs==2.4.0
      - pluggy==1.0.0
      - py==1.11.0
      - pycodestyle==2.9.1
      - pydocstyle==6.3.0
      - pyflakes==2.5.0
      - pylint==2.13.9
      - pyparsing==3.1.4
      - pytest==7.0.1
      - pytest-cov==4.0.0
      - python-dateutil==2.9.0.post0
      - pytz==2025.2
      - requests==2.27.1
      - scipy==1.5.4
      - six==1.17.0
      - snowballstemmer==2.2.0
      - soupsieve==2.3.2.post1
      - tomli==1.2.3
      - typed-ast==1.5.5
      - typing-extensions==4.1.1
      - uncertainties==3.1.7
      - urllib3==1.26.20
      - webencodings==0.5.1
      - wrapt==1.16.0
      - zipp==3.6.0
prefix: /opt/conda/envs/becquerel

tests/spectrum_test.py::test_listmode
tests/spectrum_test.py::TestSpectrumFromFile::test_spe tests/spectrum_test.py::TestSpectrumFromFile::test_spc tests/spectrum_test.py::TestSpectrumFromFile::test_cnf tests/spectrum_test.py::TestSpectrumFromFile::test_error tests/spectrum_test.py::test_uncal tests/spectrum_test.py::test_uncal_cps tests/spectrum_test.py::test_cal tests/spectrum_test.py::test_init_exceptions tests/spectrum_test.py::test_uncalibrated_exception tests/spectrum_test.py::test_negative_input tests/spectrum_test.py::test_repr tests/spectrum_test.py::test_str tests/spectrum_test.py::test_livetime_arg[86400] tests/spectrum_test.py::test_livetime_arg[300.6] tests/spectrum_test.py::test_livetime_arg[0.88] tests/spectrum_test.py::test_livetime_arg_cps[86400] tests/spectrum_test.py::test_livetime_arg_cps[300.6] tests/spectrum_test.py::test_livetime_arg_cps[0.88] tests/spectrum_test.py::test_no_livetime tests/spectrum_test.py::test_acqtime_construction[3600-start0-stop0] tests/spectrum_test.py::test_acqtime_construction[3600-2017-01-19 tests/spectrum_test.py::test_acqtime_construction[3600-start2-2017-01-01 tests/spectrum_test.py::test_acqtime_construction[2345.6-start0-stop0] tests/spectrum_test.py::test_acqtime_construction[2345.6-2017-01-19 tests/spectrum_test.py::test_acqtime_construction[2345.6-start2-2017-01-01 tests/spectrum_test.py::test_bad_acqtime_construction[2017-01-19 tests/spectrum_test.py::test_bad_realtime_livetime tests/spectrum_test.py::test_construct_float_int tests/spectrum_test.py::test_construct_ufloat tests/spectrum_test.py::test_construct_float_int_uncs tests/spectrum_test.py::test_construct_errors tests/spectrum_test.py::test_properties tests/spectrum_test.py::test_bin_widths_kev tests/spectrum_test.py::test_bin_widths_uncal tests/spectrum_test.py::test_cps[construction_kwargs0] tests/spectrum_test.py::test_cps[construction_kwargs1] tests/spectrum_test.py::test_cpskev[86400] tests/spectrum_test.py::test_cpskev[300.6] tests/spectrum_test.py::test_cpskev[0.88] tests/spectrum_test.py::test_cps_cpsspec[86400] tests/spectrum_test.py::test_cps_cpsspec[300.6] tests/spectrum_test.py::test_cps_cpsspec[0.88] tests/spectrum_test.py::test_cps_errors tests/spectrum_test.py::test_cpskev_errors tests/spectrum_test.py::test_add[uncal-uncal-300-600] tests/spectrum_test.py::test_add[uncal-uncal-12.6-0.88] tests/spectrum_test.py::test_add[uncal-uncal-300-12.6] tests/spectrum_test.py::test_add[uncal-uncal-12.6-None] tests/spectrum_test.py::test_add[uncal-uncal-None-None] tests/spectrum_test.py::test_add[cal-cal-300-600] tests/spectrum_test.py::test_add[cal-cal-12.6-0.88] tests/spectrum_test.py::test_add[cal-cal-300-12.6] tests/spectrum_test.py::test_add[cal-cal-12.6-None] tests/spectrum_test.py::test_add[cal-cal-None-None] tests/spectrum_test.py::test_add_sub_errors[uncal-cal-SpectrumError] tests/spectrum_test.py::test_add_sub_errors[uncal-uncal_long-SpectrumError] tests/spectrum_test.py::test_add_sub_errors[uncal-data-TypeError0] tests/spectrum_test.py::test_add_sub_errors[data-uncal-TypeError] tests/spectrum_test.py::test_add_sub_errors[uncal-5-TypeError] tests/spectrum_test.py::test_add_sub_errors[5-cal-TypeError] tests/spectrum_test.py::test_add_sub_errors[cal-asdf-TypeError] tests/spectrum_test.py::test_add_sub_errors[asdf-uncal-TypeError] tests/spectrum_test.py::test_add_sub_errors[uncal-data-TypeError1] tests/spectrum_test.py::test_add_sub_errors[cal-cal_new-NotImplementedError] tests/spectrum_test.py::test_add_uncs[uncal-uncal] tests/spectrum_test.py::test_add_uncs[cal-cal] tests/spectrum_test.py::test_add_sub_cps[uncal_cps-uncal_cps-300-12.6] tests/spectrum_test.py::test_add_sub_cps[uncal_cps-uncal_cps-None-12.6] tests/spectrum_test.py::test_add_sub_cps[uncal_cps-uncal_cps-None-None] tests/spectrum_test.py::test_adddition_errors[uncal-uncal_cps-None-None] tests/spectrum_test.py::test_adddition_errors[uncal_cps-uncal-None-None] tests/spectrum_test.py::test_adddition_errors[uncal-uncal_cps-300-None] tests/spectrum_test.py::test_adddition_errors[uncal_cps-uncal-None-300] tests/spectrum_test.py::test_adddition_errors[uncal-uncal_cps-300-600] tests/spectrum_test.py::test_adddition_errors[uncal_cps-uncal-600-300] tests/spectrum_test.py::test_subtract_counts[uncal-uncal-300-600] tests/spectrum_test.py::test_subtract_counts[uncal-uncal-12.6-0.88] tests/spectrum_test.py::test_subtract_counts[uncal-uncal-300-12.6] tests/spectrum_test.py::test_subtract_counts[cal-cal-300-600] tests/spectrum_test.py::test_subtract_counts[cal-cal-12.6-0.88] tests/spectrum_test.py::test_subtract_counts[cal-cal-300-12.6] tests/spectrum_test.py::test_subtract_errors[uncal-uncal_cps-None-None] tests/spectrum_test.py::test_subtract_errors[uncal_cps-uncal-None-None] tests/spectrum_test.py::test_subtract_errors[uncal-uncal_cps-None-300] tests/spectrum_test.py::test_subtract_errors[uncal_cps-uncal-300-None] tests/spectrum_test.py::test_subtract_errors[uncal-uncal_cps-300-None] tests/spectrum_test.py::test_subtract_errors[uncal_cps-uncal-None-300] tests/spectrum_test.py::test_basic_mul_div[uncal-0.88] tests/spectrum_test.py::test_basic_mul_div[uncal-1] tests/spectrum_test.py::test_basic_mul_div[uncal-2] tests/spectrum_test.py::test_basic_mul_div[uncal-43.6] tests/spectrum_test.py::test_basic_mul_div[cal-0.88] tests/spectrum_test.py::test_basic_mul_div[cal-1] tests/spectrum_test.py::test_basic_mul_div[cal-2] tests/spectrum_test.py::test_basic_mul_div[cal-43.6] tests/spectrum_test.py::test_cps_mul_div[0.88] tests/spectrum_test.py::test_cps_mul_div[1] tests/spectrum_test.py::test_cps_mul_div[2] tests/spectrum_test.py::test_cps_mul_div[43.6] tests/spectrum_test.py::test_uncal_mul_div_uncertainties[uncal-factor0] tests/spectrum_test.py::test_uncal_mul_div_uncertainties[uncal-factor1] tests/spectrum_test.py::test_uncal_mul_div_uncertainties[uncal-factor2] tests/spectrum_test.py::test_uncal_mul_div_uncertainties[cal-factor0] tests/spectrum_test.py::test_uncal_mul_div_uncertainties[cal-factor1] tests/spectrum_test.py::test_uncal_mul_div_uncertainties[cal-factor2] tests/spectrum_test.py::test_mul_div_errors[uncal-uncal-TypeError] tests/spectrum_test.py::test_mul_div_errors[uncal-asdf-TypeError] tests/spectrum_test.py::test_mul_div_errors[uncal-data-TypeError] tests/spectrum_test.py::test_mul_div_errors[uncal-0-ValueError] tests/spectrum_test.py::test_mul_div_errors[uncal-inf-ValueError] tests/spectrum_test.py::test_mul_div_errors[uncal-nan-ValueError] tests/spectrum_test.py::test_mul_div_errors[uncal-type26-ValueError] tests/spectrum_test.py::test_mul_div_errors[uncal-type27-ValueError] tests/spectrum_test.py::test_calibrate_like tests/spectrum_test.py::test_recalibrate_like tests/spectrum_test.py::test_calibrate_like_error tests/spectrum_test.py::test_calibrate_like_copy tests/spectrum_test.py::test_combine_bins[uncal] tests/spectrum_test.py::test_combine_bins[cal] tests/spectrum_test.py::test_combine_bins[uncal_cps] tests/spectrum_test.py::test_combine_bins_padding[uncal] tests/spectrum_test.py::test_combine_bins_padding[cal] tests/spectrum_test.py::test_combine_bins_padding[uncal_cps] tests/spectrum_test.py::test_downsample[2-uncal] tests/spectrum_test.py::test_downsample[2-cal] tests/spectrum_test.py::test_downsample[1.5-uncal] tests/spectrum_test.py::test_downsample[1.5-cal] tests/spectrum_test.py::test_downsample[999.99-uncal] tests/spectrum_test.py::test_downsample[999.99-cal] tests/spectrum_test.py::test_no_downsample tests/spectrum_test.py::test_zero_downsample tests/spectrum_test.py::test_downsample_handle_livetime tests/spectrum_test.py::test_downsample_error tests/spectrum_test.py::test_downsample_cps_error tests/spectrum_test.py::test_downsample_handle_livetime_error tests/spectrum_test.py::test_len[1] tests/spectrum_test.py::test_len[8] tests/spectrum_test.py::test_len[256] tests/spectrum_test.py::test_len[16384] tests/spectrum_test.py::test_len_cps[1-86400] tests/spectrum_test.py::test_len_cps[1-300.6] tests/spectrum_test.py::test_len_cps[1-0.88] tests/spectrum_test.py::test_len_cps[8-86400] tests/spectrum_test.py::test_len_cps[8-300.6] tests/spectrum_test.py::test_len_cps[8-0.88] tests/spectrum_test.py::test_len_cps[256-86400] tests/spectrum_test.py::test_len_cps[256-300.6] tests/spectrum_test.py::test_len_cps[256-0.88] tests/spectrum_test.py::test_len_cps[16384-86400] tests/spectrum_test.py::test_len_cps[16384-300.6] tests/spectrum_test.py::test_len_cps[16384-0.88] tests/spectrum_test.py::test_copy_uncal tests/spectrum_test.py::test_copy_cal tests/spectrum_test.py::test_spectrum_rebin_failure[uncalibrated tests/spectrum_test.py::test_spectrum_rebin_failure[calibrated tests/spectrum_test.py::test_spectrum_rebin_success[calibrated tests/spectrum_test.py::test_spectrum_rebin_like
becquerel/core/spectrum.py examples/spectrum.ipynb
becquerel/core/spectrum.py examples/spectrum.ipynb