Repository: cta-observatory/ctapipe
Pull request #1914 (2022-05-23 16:38:57)

Directly return peak position from neighbor average waveform
This is a small change to not compute the full array of average neighbor waveforms for each pixel and then in a separate numpy call calculate the peak position but do it directly in the same numba function.

This reduces memory usage and call overhead, runtime is divided in half from 800 to 400 µs for this test case:


```
import numpy as np
from ctapipe.instrument import TelescopeDescription, SubarrayDescription
import astropy.units as u
from ctapipe.image.extractor import NeighborPeakWindowSum
from timeit import repeat


tel = TelescopeDescription.from_name('LST', 'LSTCam')
geom = tel.camera.geometry
subarray = SubarrayDescription(
    'perf',
    tel_positions={1: [0, 0, 0] * u.m},
    tel_descriptions={1: tel},
)


extractor = NeighborPeakWindowSum(subarray)

waveforms = np.random.normal(size=(geom.n_pixels, 40)).astype('float32')
selected_gain_channels = np.zeros(geom.n_pixels, dtype=int)


# number_of_islands(geom, mask)
code = '''
extractor(waveforms, 1, selected_gain_channels)
'''

exec(code)

N = 200
times = np.array(repeat(code, number=N, repeat=10, globals=globals()))
print(f'{np.mean(times / N) * 1e6:.2f} ± {np.std(times / N) * 1e6:.2f} µs')
```



Patch:
diff --git a/ctapipe/image/__init__.py b/ctapipe/image/__init__.py
index 01fbde96..5264cb0e 100644
--- a/ctapipe/image/__init__.py
+++ b/ctapipe/image/__init__.py
@@ -45,7 +45,7 @@ from .extractor import (
     TwoPassWindowSum,
     extract_around_peak,
     extract_sliding_window,
-    neighbor_average_waveform,
+    neighbor_average_maximum,
     subtract_baseline,
     integration_correction,
 )
@@ -110,7 +110,7 @@ __all__ = [
     "TwoPassWindowSum",
     "extract_around_peak",
     "extract_sliding_window",
-    "neighbor_average_waveform",
+    "neighbor_average_maximum",
     "subtract_baseline",
     "integration_correction",
     "DataVolumeReducer",
diff --git a/ctapipe/image/extractor.py b/ctapipe/image/extractor.py
index 34343bd3..a36c35b9 100644
--- a/ctapipe/image/extractor.py
+++ b/ctapipe/image/extractor.py
@@ -14,7 +14,7 @@ __all__ = [
     "TwoPassWindowSum",
     "extract_around_peak",
     "extract_sliding_window",
-    "neighbor_average_waveform",
+    "neighbor_average_maximum",
     "subtract_baseline",
     "integration_correction",
 ]
@@ -195,7 +195,7 @@ def extract_sliding_window(waveforms, width, sampling_rate_ghz, sum_, peak_time)
 
 
 @njit(cache=True)
-def neighbor_average_waveform(waveforms, neighbors_indices, neighbors_indptr, lwt):
+def neighbor_average_maximum(waveforms, neighbors_indices, neighbors_indptr, lwt):
     """
     Obtain the average waveform built from the neighbors of each pixel
 
@@ -228,19 +228,18 @@ def neighbor_average_waveform(waveforms, neighbors_indices, neighbors_indptr, lw
 
     # initialize to waveforms weighted with lwt
     # so the value of the pixel itself is already taken into account
-    average = waveforms * lwt
+    peak_pos = np.empty(n_pixels, dtype=np.int64)
 
     for pixel in prange(n_pixels):
+        average = waveforms[pixel] * lwt
         neighbors = indices[indptr[pixel] : indptr[pixel + 1]]
 
-        n = lwt
         for neighbor in neighbors:
-            average[pixel] += waveforms[neighbor]
-            n += 1
+            average += waveforms[neighbor]
 
-        average[pixel] /= n
+        peak_pos[pixel] = np.argmax(average)
 
-    return average
+    return peak_pos
 
 
 def subtract_baseline(waveforms, baseline_start, baseline_end):
@@ -751,13 +750,12 @@ class NeighborPeakWindowSum(ImageExtractor):
 
     def __call__(self, waveforms, telid, selected_gain_channel):
         neighbors = self.subarray.tel[telid].camera.geometry.neighbor_matrix_sparse
-        average_wfs = neighbor_average_waveform(
+        peak_index = neighbor_average_maximum(
             waveforms,
             neighbors_indices=neighbors.indices,
             neighbors_indptr=neighbors.indptr,
             lwt=self.lwt.tel[telid],
         )
-        peak_index = average_wfs.argmax(axis=-1)
         charge, peak_time = extract_around_peak(
             waveforms,
             peak_index,
diff --git a/ctapipe/io/eventseeker.py b/ctapipe/io/eventseeker.py
index bb77b069..3c58643d 100644
--- a/ctapipe/io/eventseeker.py
+++ b/ctapipe/io/eventseeker.py
@@ -28,7 +28,7 @@ class EventSeeker(Component):
     To obtain a particular event in a simtel file:
 
     >>> from ctapipe.io import SimTelEventSource
-    >>> event_source = SimTelEventSource(input_url="dataset://gamma_test_large.simtel.gz", focal_length_choice="nominal")
+    >>> event_source = SimTelEventSource(input_url="dataset://gamma_test_large.simtel.gz")
     >>> seeker = EventSeeker(event_source=event_source)
     >>> event = seeker.get_event_index(2)
     >>> print(event.count)
@@ -37,7 +37,7 @@ class EventSeeker(Component):
     To obtain a particular event in a simtel file from its event_id:
 
     >>> from ctapipe.io import SimTelEventSource
-    >>> event_source = SimTelEventSource(input_url="dataset://gamma_test_large.simtel.gz", back_seekable=True, focal_length_choice="nominal")
+    >>> event_source = SimTelEventSource(input_url="dataset://gamma_test_large.simtel.gz", back_seekable=True)
     >>> seeker = EventSeeker(event_source=event_source)
     >>> event = seeker.get_event_id(31007)
     >>> print(event.count)
diff --git a/ctapipe/io/eventsource.py b/ctapipe/io/eventsource.py
index 61a9c50c..4b46f33c 100644
--- a/ctapipe/io/eventsource.py
+++ b/ctapipe/io/eventsource.py
@@ -36,7 +36,7 @@ class EventSource(Component):
     appropriate subclass if a compatible source is found for the given
     ``input_url``.
 
-    >>> EventSource(input_url="dataset://gamma_prod5.simtel.zst")
+    >>> EventSource(input_url="dataset://gamma_test_large.simtel.gz")
     <ctapipe.io.simteleventsource.SimTelEventSource ...>
 
     An ``EventSource`` can also be created through the configuration system,
@@ -45,7 +45,7 @@ class EventSource(Component):
     >>> self.source = EventSource(parent=self) # doctest: +SKIP
 
     To loop through the events in a file:
-    >>> source = EventSource(input_url="dataset://gamma_prod5.simtel.zst", max_events=2)
+    >>> source = EventSource(input_url="dataset://gamma_test_large.simtel.gz", max_events=2)
     >>> for event in source:
     ...     print(event.count)
     0
@@ -58,7 +58,7 @@ class EventSource(Component):
     It is encouraged to use ``EventSource`` in a context manager to ensure
     the correct cleanups are performed when you are finished with the source:
 
-    >>> with EventSource(input_url="dataset://gamma_prod5.simtel.zst", max_events=2) as source:
+    >>> with EventSource(input_url="dataset://gamma_test_large.simtel.gz", max_events=2) as source:
     ...    for event in source:
     ...        print(event.count)
     0
diff --git a/ctapipe/io/simteleventsource.py b/ctapipe/io/simteleventsource.py
index cdab4f59..853a4791 100644
--- a/ctapipe/io/simteleventsource.py
+++ b/ctapipe/io/simteleventsource.py
@@ -180,7 +180,7 @@ class SimTelEventSource(EventSource):
 
     focal_length_choice = CaselessStrEnum(
         ["nominal", "effective"],
-        default_value="effective",
+        default_value="nominal",
         help=(
             "if both nominal and effective focal lengths are available in the "
             "SimTelArray file, which one to use when constructing the "
@@ -306,31 +306,26 @@ class SimTelEventSource(EventSource):
             pixel_settings = telescope_description["pixel_settings"]
 
             n_pixels = cam_settings["n_pixels"]
+            focal_length = u.Quantity(cam_settings["focal_length"], u.m)
             mirror_area = u.Quantity(cam_settings["mirror_area"], u.m**2)
 
-            nominal_focal_length = u.Quantity(cam_settings["focal_length"], u.m)
-            effective_focal_length = u.Quantity(
-                cam_settings.get("effective_focal_length", np.nan), u.m
-            )
+            if self.focal_length_choice == "effective":
+                try:
+                    focal_length = u.Quantity(
+                        cam_settings["effective_focal_length"], u.m
+                    )
+                except KeyError as err:
+                    raise RuntimeError(
+                        f"the SimTelEventSource option 'focal_length_choice' was set to "
+                        f"{self.focal_length_choice}, but the effective focal length "
+                        f"was not present in the file. ({err})"
+                    )
 
             try:
-                telescope = guess_telescope(n_pixels, nominal_focal_length)
+                telescope = guess_telescope(n_pixels, focal_length)
             except ValueError:
                 telescope = unknown_telescope(mirror_area, n_pixels)
 
-            if self.focal_length_choice == "effective":
-                if np.isnan(effective_focal_length):
-                    raise RuntimeError(
-                        f"`SimTelEventSource.focal_length_choice` was set to"
-                        f" {self.focal_length_choice!r}, but the effective focal length"
-                        f" was not present in the file. "
-                        " Use nominal focal length or adapt your simulation configuration"
-                        " to include the effective focal length"
-                    )
-                focal_length = effective_focal_length
-            else:
-                focal_length = nominal_focal_length
-
             optics = OpticsDescription(
                 name=telescope.name,
                 num_mirrors=telescope.n_mirrors,
diff --git a/ctapipe/utils/datasets.py b/ctapipe/utils/datasets.py
index 71ba6148..42f187f2 100644
--- a/ctapipe/utils/datasets.py
+++ b/ctapipe/utils/datasets.py
@@ -28,7 +28,7 @@ logger = logging.getLogger(__name__)
 __all__ = ["get_dataset_path", "find_in_path", "find_all_matching_datasets"]
 
 
-DEFAULT_URL = "http://cccta-dataserver.in2p3.fr/data/ctapipe-extra/v0.3.4/"
+DEFAULT_URL = "http://cccta-dataserver.in2p3.fr/data/ctapipe-extra/v0.3.3/"
 
 
 def get_searchpath_dirs(searchpath=os.getenv("CTAPIPE_SVC_PATH"), url=DEFAULT_URL):
diff --git a/docs/examples/InstrumentDescription.ipynb b/docs/examples/InstrumentDescription.ipynb
index dbefaa51..f70a901c 100644
--- a/docs/examples/InstrumentDescription.ipynb
+++ b/docs/examples/InstrumentDescription.ipynb
@@ -21,7 +21,8 @@
     "from ctapipe.io import EventSource\n",
     "import numpy as np\n",
     "\n",
-    "filename = get_dataset_path(\"gamma_prod5.simtel.zst\")  \n",
+    "#filename = get_dataset_path(\"gamma_test_large.simtel.gz\") # try this one as well\n",
+    "filename = get_dataset_path(\"gamma_test_large.simtel.gz\")  \n",
     "\n",
     "with EventSource(filename, max_events=1) as source:\n",
     "    subarray = source.subarray"
@@ -358,7 +359,7 @@
  ],
  "metadata": {
   "kernelspec": {
-   "display_name": "Python 3 (ipykernel)",
+   "display_name": "Python 3",
    "language": "python",
    "name": "python3"
   },
@@ -372,7 +373,7 @@
    "name": "python",
    "nbconvert_exporter": "python",
    "pygments_lexer": "ipython3",
-   "version": "3.8.13"
+   "version": "3.7.10"
   }
  },
  "nbformat": 4,
diff --git a/docs/tutorials/calibrated_data_exploration.ipynb b/docs/tutorials/calibrated_data_exploration.ipynb
index 725d29d8..d2c5bddf 100644
--- a/docs/tutorials/calibrated_data_exploration.ipynb
+++ b/docs/tutorials/calibrated_data_exploration.ipynb
@@ -48,7 +48,7 @@
    "metadata": {},
    "outputs": [],
    "source": [
-    "filename = get_dataset_path(\"gamma_prod5.simtel.zst\")\n",
+    "filename = get_dataset_path(\"gamma_test.simtel.gz\")\n",
     "source = EventSource(filename, max_events=2)\n",
     "\n",
     "for event in source:\n",
@@ -85,9 +85,7 @@
   {
    "cell_type": "code",
    "execution_count": null,
-   "metadata": {
-    "scrolled": false
-   },
+   "metadata": {},
    "outputs": [],
    "source": [
     "print(event.r1)"
@@ -353,18 +351,11 @@
     "ad.values = hit_pattern\n",
     "ad.add_labels()\n"
    ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": []
   }
  ],
  "metadata": {
   "kernelspec": {
-   "display_name": "Python 3 (ipykernel)",
+   "display_name": "Python 3",
    "language": "python",
    "name": "python3"
   },
@@ -378,7 +369,7 @@
    "name": "python",
    "nbconvert_exporter": "python",
    "pygments_lexer": "ipython3",
-   "version": "3.8.13"
+   "version": "3.7.10"
   }
  },
  "nbformat": 4,
diff --git a/docs/tutorials/coordinates_example.ipynb b/docs/tutorials/coordinates_example.ipynb
index 429efc7e..6f6d2d47 100644
--- a/docs/tutorials/coordinates_example.ipynb
+++ b/docs/tutorials/coordinates_example.ipynb
@@ -90,11 +90,11 @@
    },
    "outputs": [],
    "source": [
-    "filename = get_dataset_path(\"gamma_prod5.simtel.zst\")\n",
-    "source = EventSource(filename)\n",
+    "filename = get_dataset_path(\"gamma_test_large.simtel.gz\")\n",
+    "source = EventSource(filename, max_events=4)\n",
     "\n",
     "events = [copy.deepcopy(event) for event in source]\n",
-    "event = events[4]\n",
+    "event = events[3]\n",
     "\n",
     "layout = set(source.subarray.tel_ids)  "
    ]
@@ -123,8 +123,8 @@
    },
    "outputs": [],
    "source": [
-    "print(f'Telescope with data: {event.r1.tel.keys()}')\n",
-    "tel_id = 3"
+    "print(f'Telescope with data: {event.r0.tel.keys()}')\n",
+    "tel_id = 2"
    ]
   },
   {
@@ -620,7 +620,7 @@
  ],
  "metadata": {
   "kernelspec": {
-   "display_name": "Python 3 (ipykernel)",
+   "display_name": "Python 3",
    "language": "python",
    "name": "python3"
   },
@@ -634,7 +634,7 @@
    "name": "python",
    "nbconvert_exporter": "python",
    "pygments_lexer": "ipython3",
-   "version": "3.8.13"
+   "version": "3.7.10"
   }
  },
  "nbformat": 4,
diff --git a/docs/tutorials/ctapipe_handson.ipynb b/docs/tutorials/ctapipe_handson.ipynb
index 68115dfd..d9ce8fd3 100644
--- a/docs/tutorials/ctapipe_handson.ipynb
+++ b/docs/tutorials/ctapipe_handson.ipynb
@@ -35,7 +35,7 @@
    "metadata": {},
    "outputs": [],
    "source": [
-    "path = utils.get_dataset_path(\"gamma_prod5.simtel.zst\")"
+    "path = utils.get_dataset_path(\"gamma_test_large.simtel.gz\")"
    ]
   },
   {
@@ -44,7 +44,7 @@
    "metadata": {},
    "outputs": [],
    "source": [
-    "source = EventSource(path, max_events=5)\n",
+    "source = EventSource(path, max_events=4)\n",
     "\n",
     "for event in source:\n",
     "    print(event.count, event.index.event_id, event.simulation.shower.energy)"
@@ -65,7 +65,7 @@
    "metadata": {},
    "outputs": [],
    "source": [
-    "event.r1"
+    "event.r0"
    ]
   },
   {
@@ -74,8 +74,8 @@
    "metadata": {},
    "outputs": [],
    "source": [
-    "for event in EventSource(path, max_events=5):\n",
-    "    print(event.count, event.r1.tel.keys())"
+    "for event in EventSource(path, max_events=4):\n",
+    "    print(event.count, event.r0.tel.keys())"
    ]
   },
   {
@@ -84,7 +84,7 @@
    "metadata": {},
    "outputs": [],
    "source": [
-    "event.r0.tel[3]"
+    "event.r0.tel[2]"
    ]
   },
   {
@@ -366,7 +366,7 @@
    "metadata": {},
    "outputs": [],
    "source": [
-    "for event in EventSource(path, max_events=5):\n",
+    "for event in EventSource(path, max_events=4):\n",
     "    calib(event) # fills in r1, dl0, and dl1\n",
     "    print(event.dl1.tel.keys())"
    ]
@@ -480,8 +480,8 @@
     "disp = CameraDisplay(tel.camera.geometry, image=cleaned)\n",
     "disp.cmap = plt.cm.coolwarm\n",
     "disp.add_colorbar()\n",
-    "plt.xlim(0.5, 1.0)\n",
-    "plt.ylim(-1.0, 0.0)"
+    "plt.xlim(-1.0,0)\n",
+    "plt.ylim(0,1.0)"
    ]
   },
   {
@@ -503,8 +503,8 @@
     "disp = CameraDisplay(tel.camera.geometry, image=cleaned)\n",
     "disp.cmap = plt.cm.coolwarm\n",
     "disp.add_colorbar()\n",
-    "plt.xlim(0.5, 1.0)\n",
-    "plt.ylim(-1.0, 0.0)\n",
+    "plt.xlim(-1.0,0)\n",
+    "plt.ylim(0,1.0)\n",
     "disp.overlay_moments(params, color='white', lw=2)"
    ]
   },
@@ -557,8 +557,8 @@
    "metadata": {},
    "outputs": [],
    "source": [
-    "data = utils.get_dataset_path(\"gamma_prod5.simtel.zst\") \n",
-    "source = EventSource(data) # remove the max_events limit to get more stats"
+    "data = utils.get_dataset_path(\"gamma_test_large.simtel.gz\") \n",
+    "source = EventSource(data, allowed_tels=[1,2,3,4],  max_events=10) # remove the max_events limit to get more stats"
    ]
   },
   {
@@ -573,8 +573,7 @@
     "    for tel_id, tel_data in event.dl1.tel.items():\n",
     "        tel = source.subarray.tel[tel_id]\n",
     "        mask = tailcuts_clean(tel.camera.geometry, tel_data.image)\n",
-    "        if np.count_nonzero(mask) > 0:\n",
-    "            params = hillas_parameters(tel.camera.geometry[mask], tel_data.image[mask])"
+    "        params = hillas_parameters(tel.camera.geometry[mask], tel_data.image[mask])"
    ]
   },
   {
@@ -646,13 +645,20 @@
    "cell_type": "markdown",
    "metadata": {},
    "source": [
-    "If you do this yourself, chose a larger file to loop over more events to get better statistics"
+    "If you do this yourself, loop over more events to get better statistics"
    ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
   }
  ],
  "metadata": {
   "kernelspec": {
-   "display_name": "Python 3 (ipykernel)",
+   "display_name": "Python 3",
    "language": "python",
    "name": "python3"
   },
@@ -666,7 +672,7 @@
    "name": "python",
    "nbconvert_exporter": "python",
    "pygments_lexer": "ipython3",
-   "version": "3.8.13"
+   "version": "3.7.8"
   }
  },
  "nbformat": 4,
diff --git a/docs/tutorials/ctapipe_overview.ipynb b/docs/tutorials/ctapipe_overview.ipynb
index 64ae83a4..0c4b98f1 100644
--- a/docs/tutorials/ctapipe_overview.ipynb
+++ b/docs/tutorials/ctapipe_overview.ipynb
@@ -222,11 +222,11 @@
     "from ctapipe.io import EventSource\n",
     "from ctapipe.utils.datasets import get_dataset_path\n",
     "\n",
-    "input_url = get_dataset_path('gamma_prod5.simtel.zst')\n",
+    "input_url = get_dataset_path('gamma_test_large.simtel.gz')\n",
     "\n",
     "# EventSource() automatically detects what kind of file we are giving it,\n",
     "# if already supported by ctapipe\n",
-    "source = EventSource(input_url, max_events=5)\n",
+    "source = EventSource(input_url, max_events=49)\n",
     "\n",
     "print(type(source))"
    ]
@@ -351,7 +351,7 @@
    },
    "outputs": [],
    "source": [
-    "tel_id = 130"
+    "tel_id = 4"
    ]
   },
   {
@@ -425,12 +425,12 @@
    },
    "outputs": [],
    "source": [
-    "# unoptimized cleaning levels\n",
+    "# unoptimized cleaning levels, copied from \n",
+    "# https://github.com/tudo-astroparticlephysics/cta_preprocessing\n",
     "cleaning_level = {\n",
-    "    'CHEC': (2, 4, 2),\n",
-    "    'LSTCam': (3.5, 7, 2),\n",
-    "    'FlashCam': (3.5, 7, 2), \n",
-    "    'NectarCam': (4, 8, 2), \n",
+    "    'ASTRICam': (5, 7, 2),  # (5, 10)?\n",
+    "    'LSTCam': (3.5, 7.5, 2),  # ?? (3, 6) for Abelardo...\n",
+    "    'FlashCam': (4, 8, 2),  # there is some scaling missing?\n",
     "}"
    ]
   },
@@ -675,21 +675,19 @@
     "            \"picture_threshold_pe\": [\n",
     "                (\"type\", \"LST_LST_LSTCam\", 7.5),\n",
     "                (\"type\", \"MST_MST_FlashCam\", 8),\n",
-    "                (\"type\", \"MST_MST_NectarCam\", 8),\n",
-    "                (\"type\", \"SST_ASTRI_CHEC\", 7),\n",
+    "                (\"type\", \"SST_ASTRI_ASTRICam\", 7),\n",
     "            ],\n",
     "            \"boundary_threshold_pe\": [\n",
     "                (\"type\", \"LST_LST_LSTCam\", 5),\n",
     "                (\"type\", \"MST_MST_FlashCam\", 4),\n",
-    "                (\"type\", \"MST_MST_NectarCam\", 4),\n",
-    "                (\"type\", \"SST_ASTRI_CHEC\", 4),\n",
+    "                (\"type\", \"SST_ASTRI_ASTRICam\", 4),\n",
     "            ]\n",
     "            \n",
     "        }\n",
     "    }\n",
     "})\n",
     "\n",
-    "input_url = get_dataset_path('gamma_prod5.simtel.zst')\n",
+    "input_url = get_dataset_path('gamma_test_large.simtel.gz')\n",
     "source = EventSource(input_url)\n",
     "\n",
     "calibrator = CameraCalibrator(subarray=source.subarray)\n",
@@ -811,8 +809,8 @@
     ")\n",
     "\n",
     "plt.legend()\n",
-    "# plt.xlim(-400, 400)\n",
-    "# plt.ylim(-400, 400)"
+    "plt.xlim(-400, 400)\n",
+    "plt.ylim(-400, 400)"
    ]
   },
   {
diff --git a/docs/tutorials/raw_data_exploration.ipynb b/docs/tutorials/raw_data_exploration.ipynb
index 884fd025..6c2d6320 100644
--- a/docs/tutorials/raw_data_exploration.ipynb
+++ b/docs/tutorials/raw_data_exploration.ipynb
@@ -24,12 +24,11 @@
    "outputs": [],
    "source": [
     "from ctapipe.utils import get_dataset_path\n",
-    "from ctapipe.io import EventSource\n",
+    "from ctapipe.io import EventSource, EventSeeker\n",
     "from ctapipe.visualization import CameraDisplay\n",
     "from ctapipe.instrument import CameraGeometry\n",
     "from matplotlib import pyplot as plt\n",
     "from astropy import units as u\n",
-    "\n",
     "%matplotlib inline"
    ]
   },
@@ -48,7 +47,8 @@
    "metadata": {},
    "outputs": [],
    "source": [
-    "source = EventSource(get_dataset_path(\"gamma_prod5.simtel.zst\"), max_events=5)"
+    "source = EventSource(get_dataset_path(\"gamma_test_large.simtel.gz\"), max_events=100, back_seekable=True)\n",
+    "seeker = EventSeeker(source)"
    ]
   },
   {
@@ -66,10 +66,8 @@
    "metadata": {},
    "outputs": [],
    "source": [
-    "# so we can advance through events one-by-one\n",
-    "event_iterator = iter(source)\n",
-    "\n",
-    "event = next(event_iterator)"
+    "event = seeker.get_event_index(3)  # get 3rd event\n",
+    "event"
    ]
   },
   {
@@ -85,7 +83,7 @@
    "metadata": {},
    "outputs": [],
    "source": [
-    "event.r0"
+    "print(repr(event.r0))"
    ]
   },
   {
@@ -117,7 +115,7 @@
    "cell_type": "markdown",
    "metadata": {},
    "source": [
-    "note that the event has 3 telescopes in it: Let's try the next one:"
+    "note that the event has 2 telescopes in it: 38,40... Let's try the next one:"
    ]
   },
   {
@@ -126,7 +124,7 @@
    "metadata": {},
    "outputs": [],
    "source": [
-    "event = next(event_iterator)\n",
+    "event = seeker.get_event_index(5) # get the next event\n",
     "print(event.r0.tel.keys())"
    ]
   },
@@ -134,7 +132,7 @@
    "cell_type": "markdown",
    "metadata": {},
    "source": [
-    "now, we have a larger event with many telescopes... Let's look at one of them:"
+    "now, we have a larger event with many telescopes... Let's look at the data from **CT7**:"
    ]
   },
   {
@@ -143,7 +141,7 @@
    "metadata": {},
    "outputs": [],
    "source": [
-    "teldata = event.r0.tel[26]\n",
+    "teldata = event.r0.tel[15]\n",
     "print(teldata)\n",
     "teldata"
    ]
@@ -421,9 +419,7 @@
   {
    "cell_type": "code",
    "execution_count": null,
-   "metadata": {
-    "scrolled": false
-   },
+   "metadata": {},
    "outputs": [],
    "source": [
     "for tel in event.r0.tel.keys():\n",
@@ -492,7 +488,7 @@
  ],
  "metadata": {
   "kernelspec": {
-   "display_name": "Python 3 (ipykernel)",
+   "display_name": "Python 3",
    "language": "python",
    "name": "python3"
   },
@@ -506,7 +502,7 @@
    "name": "python",
    "nbconvert_exporter": "python",
    "pygments_lexer": "ipython3",
-   "version": "3.8.13"
+   "version": "3.7.8"
   }
  },
  "nbformat": 4,
diff --git a/docs/tutorials/theta_square.ipynb b/docs/tutorials/theta_square.ipynb
index 91191ae2..b141c586 100644
--- a/docs/tutorials/theta_square.ipynb
+++ b/docs/tutorials/theta_square.ipynb
@@ -73,10 +73,7 @@
    },
    "outputs": [],
    "source": [
-    "source = EventSource(\n",
-    "    \"dataset://gamma_prod5.simtel.zst\",\n",
-    "#     allowed_tels={1, 2, 3, 4},\n",
-    ")\n",
+    "source = EventSource(\"dataset://gamma_test_large.simtel.gz\", allowed_tels={1, 2, 3, 4})\n",
     "\n",
     "subarray = source.subarray\n",
     "\n",


Test patch:
diff --git a/ctapipe/conftest.py b/ctapipe/conftest.py
index 891d4658..cec3dcce 100644
--- a/ctapipe/conftest.py
+++ b/ctapipe/conftest.py
@@ -44,8 +44,7 @@ def _global_example_event():
 
     print("******************** LOAD TEST EVENT ***********************")
 
-    # FIXME: switch to prod5b+ file that contains effective focal length
-    with SimTelEventSource(input_url=filename, focal_length_choice='nominal') as reader:
+    with SimTelEventSource(input_url=filename) as reader:
         event = next(iter(reader))
 
     return event
@@ -60,7 +59,7 @@ def example_subarray():
 
     print("******************** LOAD TEST EVENT ***********************")
 
-    with SimTelEventSource(input_url=filename, focal_length_choice='nominal') as reader:
+    with SimTelEventSource(input_url=filename) as reader:
         return reader.subarray
 
 
@@ -85,7 +84,7 @@ def _subarray_and_event_gamma_off_axis_500_gev():
 
     path = get_dataset_path("lst_prod3_calibration_and_mcphotons.simtel.zst")
 
-    with SimTelEventSource(path, focal_length_choice='nominal') as source:
+    with SimTelEventSource(path) as source:
         it = iter(source)
         # we want the second event, first event is a corner clipper
         next(it)
@@ -354,7 +353,6 @@ def dl1_muon_file(dl1_tmp_path):
             "--write-images",
             "--DataWriter.write_parameters=False",
             "--DataWriter.Contact.name=αℓℓ the äüöß",
-            "--SimTelEventSource.focal_length_choice=nominal",
         ]
         assert run_tool(ProcessorTool(), argv=argv, cwd=dl1_tmp_path) == 0
         return output
diff --git a/ctapipe/image/tests/test_extractor.py b/ctapipe/image/tests/test_extractor.py
index 88d7a14d..fb683ec9 100644
--- a/ctapipe/image/tests/test_extractor.py
+++ b/ctapipe/image/tests/test_extractor.py
@@ -12,7 +12,7 @@ from ctapipe.image.extractor import (
     extract_around_peak,
     extract_sliding_window,
     integration_correction,
-    neighbor_average_waveform,
+    neighbor_average_maximum,
     subtract_baseline,
 )
 from ctapipe.image.toymodel import SkewedGaussian, WaveformModel, obtain_time_image
@@ -191,10 +191,10 @@ def test_extract_around_peak_charge_expected(toymodel):
     assert_equal(charge, n_samples)
 
 
-def test_neighbor_average_waveform(toymodel):
+def test_neighbor_average_peakpos(toymodel):
     waveforms, subarray, telid, _, _, _ = toymodel
     neighbors = subarray.tel[telid].camera.geometry.neighbor_matrix_sparse
-    average_wf = neighbor_average_waveform(
+    peak_pos = neighbor_average_maximum(
         waveforms,
         neighbors_indices=neighbors.indices,
         neighbors_indptr=neighbors.indptr,
@@ -204,10 +204,11 @@ def test_neighbor_average_waveform(toymodel):
     pixel = 0
     _, nei_pixel = np.where(neighbors[pixel].A)
     expected_average = waveforms[nei_pixel].sum(0) / len(nei_pixel)
-    assert_allclose(average_wf[pixel], expected_average, rtol=1e-3)
+    expected_peak_pos = np.argmax(expected_average, axis=-1)
+    assert (peak_pos[pixel] == expected_peak_pos).all()
 
     lwt = 4
-    average_wf = neighbor_average_waveform(
+    peak_pos = neighbor_average_maximum(
         waveforms,
         neighbors_indices=neighbors.indices,
         neighbors_indptr=neighbors.indptr,
@@ -218,7 +219,8 @@ def test_neighbor_average_waveform(toymodel):
     _, nei_pixel = np.where(neighbors[pixel].A)
     nei_pixel = np.concatenate([nei_pixel, [pixel] * lwt])
     expected_average = waveforms[nei_pixel].sum(0) / len(nei_pixel)
-    assert_allclose(average_wf[pixel], expected_average, rtol=1e-3)
+    expected_peak_pos = np.argmax(expected_average, axis=-1)
+    assert (peak_pos[pixel] == expected_peak_pos).all()
 
 
 def test_extract_peak_time_within_range():
@@ -532,7 +534,7 @@ def test_global_peak_window_sum_with_pixel_fraction(subarray):
 
     tel_id = 1
     camera = subarray.tel[tel_id].camera
-    sample_rate = camera.readout.sampling_rate.to_value(u.ns ** -1)
+    sample_rate = camera.readout.sampling_rate.to_value(u.ns**-1)
     n_pixels = camera.geometry.n_pixels
     selected_gain_channel = np.zeros(n_pixels, dtype=np.uint8)
 
diff --git a/ctapipe/io/tests/conftest.py b/ctapipe/io/tests/conftest.py
index 8c818a23..27705d2c 100644
--- a/ctapipe/io/tests/conftest.py
+++ b/ctapipe/io/tests/conftest.py
@@ -1,5 +1,6 @@
 import pytest
 from ctapipe.io import EventSource, DataWriter
+from ctapipe.utils import get_dataset_path
 
 
 @pytest.fixture(scope="session")
@@ -8,10 +9,11 @@ def r1_path(tmp_path_factory):
 
 
 @pytest.fixture(scope="session")
-def r1_hdf5_file(prod5_proton_simtel_path, r1_path):
+def r1_hdf5_file(r1_path):
     source = EventSource(
-        prod5_proton_simtel_path,
+        get_dataset_path("gamma_LaPalma_baseline_20Zd_180Az_prod3b_test.simtel.gz"),
         max_events=5,
+        allowed_tels=[1, 2, 3, 4],
     )
 
     path = r1_path / "test_r1.h5"
diff --git a/ctapipe/io/tests/test_datawriter.py b/ctapipe/io/tests/test_datawriter.py
index ce5d0f24..97feb96d 100644
--- a/ctapipe/io/tests/test_datawriter.py
+++ b/ctapipe/io/tests/test_datawriter.py
@@ -51,7 +51,6 @@ def test_write(tmpdir: Path):
         get_dataset_path("gamma_LaPalma_baseline_20Zd_180Az_prod3b_test.simtel.gz"),
         max_events=20,
         allowed_tels=[1, 2, 3, 4],
-        focal_length_choice='nominal',
     )
     calibrate = CameraCalibrator(subarray=source.subarray)
 
@@ -132,7 +131,6 @@ def test_roundtrip(tmpdir: Path):
         get_dataset_path("gamma_LaPalma_baseline_20Zd_180Az_prod3b_test.simtel.gz"),
         max_events=20,
         allowed_tels=[1, 2, 3, 4],
-        focal_length_choice='nominal',
     )
     calibrate = CameraCalibrator(subarray=source.subarray)
 
@@ -205,7 +203,7 @@ def test_dl1writer_no_events(tmpdir: Path):
 
     output_path = Path(tmpdir / "no_events.dl1.h5")
     dataset = "lst_prod3_calibration_and_mcphotons.simtel.zst"
-    with EventSource(get_dataset_path(dataset), focal_length_choice='nominal') as source:
+    with EventSource(get_dataset_path(dataset)) as source:
         # exhaust source
         for _ in source:
             pass
@@ -235,7 +233,7 @@ def test_dl1writer_no_events(tmpdir: Path):
 def test_metadata(tmpdir: Path):
     output_path = Path(tmpdir / "metadata.dl1.h5")
 
-    dataset = "gamma_20deg_0deg_run2___cta-prod5-paranal_desert-2147m-Paranal-dark_cone10-100evts.simtel.zst"
+    dataset = "lst_prod3_calibration_and_mcphotons.simtel.zst"
 
     config = Config(
         {
diff --git a/ctapipe/io/tests/test_event_source.py b/ctapipe/io/tests/test_event_source.py
index 9a839ff8..a46f8506 100644
--- a/ctapipe/io/tests/test_event_source.py
+++ b/ctapipe/io/tests/test_event_source.py
@@ -6,8 +6,6 @@ from traitlets import TraitError
 
 from ctapipe.core import Component
 
-prod5_path = "gamma_20deg_0deg_run2___cta-prod5-paranal_desert-2147m-Paranal-dark_cone10-100evts.simtel.zst"
-
 
 def test_construct():
     # at least one of input_url / parent / config is required
@@ -45,20 +43,20 @@ class DummyReader(EventSource):
 
 
 def test_can_be_implemented():
-    dataset = get_dataset_path(prod5_path)
+    dataset = get_dataset_path("gamma_test_large.simtel.gz")
     test_reader = DummyReader(input_url=dataset)
     assert test_reader is not None
 
 
 def test_is_iterable():
-    dataset = get_dataset_path(prod5_path)
+    dataset = get_dataset_path("gamma_test_large.simtel.gz")
     test_reader = DummyReader(input_url=dataset)
     for _ in test_reader:
         pass
 
 
 def test_function():
-    dataset = get_dataset_path(prod5_path)
+    dataset = get_dataset_path("gamma_test_large.simtel.gz")
     reader = EventSource(input_url=dataset)
     assert isinstance(reader, SimTelEventSource)
     assert reader.input_url == dataset
@@ -77,7 +75,7 @@ def test_function_nonexistant_file():
 
 
 def test_from_config():
-    dataset = get_dataset_path(prod5_path)
+    dataset = get_dataset_path("gamma_test_large.simtel.gz")
     config = Config({"EventSource": {"input_url": dataset}})
     reader = EventSource(config=config)
     assert isinstance(reader, SimTelEventSource)
@@ -85,7 +83,7 @@ def test_from_config():
 
 
 def test_from_config_parent():
-    dataset = get_dataset_path(prod5_path)
+    dataset = get_dataset_path("gamma_test_large.simtel.gz")
 
     class Parent(Component):
         def __init__(self, config=None, parent=None):
@@ -111,7 +109,7 @@ def test_from_config_parent():
 
 def test_from_config_default():
     old_default = EventSource.input_url.default_value
-    dataset = get_dataset_path(prod5_path)
+    dataset = get_dataset_path("gamma_test_large.simtel.gz")
     EventSource.input_url.default_value = dataset
     config = Config()
     reader = EventSource(config=config, parent=None)
@@ -121,7 +119,7 @@ def test_from_config_default():
 
 
 def test_from_config_invalid_type():
-    dataset = get_dataset_path(prod5_path)
+    dataset = get_dataset_path("gamma_test_large.simtel.gz")
     EventSource.input_url.default_value = dataset
     config = Config({"EventSource": {"input_url": 124}})
     with pytest.raises(TraitError):
@@ -129,10 +127,10 @@ def test_from_config_invalid_type():
 
 
 def test_event_source_input_url_config_override():
-    dataset1 = get_dataset_path(
+    dataset1 = get_dataset_path("gamma_test_large.simtel.gz")
+    dataset2 = get_dataset_path(
         "gamma_LaPalma_baseline_20Zd_180Az_prod3b_test.simtel.gz"
     )
-    dataset2 = get_dataset_path(prod5_path)
 
     config = Config({"EventSource": {"input_url": dataset1}})
     reader = EventSource(input_url=dataset2, config=config)
@@ -143,13 +141,13 @@ def test_event_source_input_url_config_override():
 
 def test_max_events():
     max_events = 10
-    dataset = get_dataset_path(prod5_path)
+    dataset = get_dataset_path("gamma_test_large.simtel.gz")
     reader = EventSource(input_url=dataset, max_events=max_events)
     assert reader.max_events == max_events
 
 
 def test_max_events_from_config():
-    dataset = get_dataset_path(prod5_path)
+    dataset = get_dataset_path("gamma_test_large.simtel.gz")
     max_events = 10
     config = Config({"EventSource": {"input_url": dataset, "max_events": max_events}})
     reader = EventSource(config=config)
@@ -157,15 +155,15 @@ def test_max_events_from_config():
 
 
 def test_allowed_tels():
-    dataset = get_dataset_path(prod5_path)
+    dataset = get_dataset_path("gamma_test_large.simtel.gz")
     reader = EventSource(input_url=dataset)
     assert reader.allowed_tels is None
     reader = EventSource(input_url=dataset, allowed_tels={1, 3})
-    assert reader.allowed_tels == {1, 3}
+    assert len(reader.allowed_tels) == 2
 
 
 def test_allowed_tels_from_config():
-    dataset = get_dataset_path(prod5_path)
+    dataset = get_dataset_path("gamma_test_large.simtel.gz")
     config = Config({"EventSource": {"input_url": dataset, "allowed_tels": {1, 3}}})
     reader = EventSource(config=config, parent=None)
-    assert reader.allowed_tels == {1, 3}
+    assert len(reader.allowed_tels) == 2
diff --git a/ctapipe/io/tests/test_eventseeker.py b/ctapipe/io/tests/test_eventseeker.py
index 58ec2547..fee3119c 100644
--- a/ctapipe/io/tests/test_eventseeker.py
+++ b/ctapipe/io/tests/test_eventseeker.py
@@ -8,11 +8,7 @@ dataset = get_dataset_path("gamma_test_large.simtel.gz")
 
 def test_eventseeker():
 
-    with SimTelEventSource(
-        input_url=dataset,
-        back_seekable=True,
-        focal_length_choice='nominal',
-    ) as reader:
+    with SimTelEventSource(input_url=dataset, back_seekable=True) as reader:
 
         seeker = EventSeeker(event_source=reader)
 
@@ -37,8 +33,7 @@ def test_eventseeker():
             seeker.get_event_index(dict())
 
     with SimTelEventSource(
-        input_url=dataset, max_events=5, back_seekable=True,
-        focal_length_choice='nominal',
+        input_url=dataset, max_events=5, back_seekable=True
     ) as reader:
         seeker = EventSeeker(event_source=reader)
         with pytest.raises(IndexError):
@@ -47,10 +42,7 @@ def test_eventseeker():
 
 
 def test_eventseeker_edit():
-    with SimTelEventSource(
-        input_url=dataset, back_seekable=True,
-        focal_length_choice='nominal',
-    ) as reader:
+    with SimTelEventSource(input_url=dataset, back_seekable=True) as reader:
         seeker = EventSeeker(event_source=reader)
         event = seeker.get_event_index(1)
         assert event.count == 1
@@ -62,10 +54,7 @@ def test_eventseeker_edit():
 
 def test_eventseeker_simtel():
     # Ensure the EventSeeker can forward seek even if back-seeking is not possible
-    with SimTelEventSource(
-        input_url=dataset, back_seekable=False,
-        focal_length_choice='nominal',
-    ) as reader:
+    with SimTelEventSource(input_url=dataset, back_seekable=False) as reader:
         seeker = EventSeeker(event_source=reader)
         event = seeker.get_event_index(1)
         assert event.count == 1
diff --git a/ctapipe/io/tests/test_hdf5eventsource.py b/ctapipe/io/tests/test_hdf5eventsource.py
index eaab48b2..a8634e79 100644
--- a/ctapipe/io/tests/test_hdf5eventsource.py
+++ b/ctapipe/io/tests/test_hdf5eventsource.py
@@ -136,4 +136,4 @@ def test_read_r1(r1_hdf5_file):
             pass
 
         assert e is not None
-        assert e.count == 3
+        assert e.count == 4
diff --git a/ctapipe/io/tests/test_prod2.py b/ctapipe/io/tests/test_prod2.py
index 98be8be0..200d2406 100644
--- a/ctapipe/io/tests/test_prod2.py
+++ b/ctapipe/io/tests/test_prod2.py
@@ -9,10 +9,7 @@ dataset = get_dataset_path("gamma_test.simtel.gz")
 
 def test_eventio_prod2():
     with pytest.warns(UnknownPixelShapeWarning):
-        with SimTelEventSource(
-            input_url=dataset,
-            focal_length_choice='nominal',
-        ) as reader:
+        with SimTelEventSource(input_url=dataset) as reader:
             for event in reader:
                 if event.count == 2:
                     break
diff --git a/ctapipe/io/tests/test_simteleventsource.py b/ctapipe/io/tests/test_simteleventsource.py
index 77eba9e8..d94a09c6 100644
--- a/ctapipe/io/tests/test_simteleventsource.py
+++ b/ctapipe/io/tests/test_simteleventsource.py
@@ -2,8 +2,8 @@ import copy
 from ctapipe.instrument.camera.geometry import UnknownPixelShapeWarning
 
 import numpy as np
+from astropy.utils.data import download_file
 import astropy.units as u
-from astropy.coordinates import Angle
 from itertools import zip_longest
 import pytest
 from astropy.time import Time
@@ -20,21 +20,18 @@ from ctapipe.io import DataLevel
 gamma_test_large_path = get_dataset_path("gamma_test_large.simtel.gz")
 gamma_test_path = get_dataset_path("gamma_test.simtel.gz")
 calib_events_path = get_dataset_path("lst_prod3_calibration_and_mcphotons.simtel.zst")
-prod5b_path = get_dataset_path("gamma_20deg_0deg_run2___cta-prod5-paranal_desert-2147m-Paranal-dark_cone10-100evts.simtel.zst")
 
 
 def test_positional_input():
-    source = SimTelEventSource(prod5b_path)
-    assert source.input_url == Path(prod5b_path)
+    source = SimTelEventSource(gamma_test_large_path)
+    assert source.input_url == Path(gamma_test_large_path)
 
 
 def test_simtel_event_source_on_gamma_test_one_event():
-    assert SimTelEventSource.is_compatible(gamma_test_large_path)
-
     with SimTelEventSource(
-        input_url=gamma_test_large_path, back_seekable=True,
-        focal_length_choice='nominal',
+        input_url=gamma_test_large_path, back_seekable=True
     ) as reader:
+        assert reader.is_compatible(gamma_test_large_path)
         assert not reader.is_stream
 
         for event in reader:
@@ -50,7 +47,7 @@ def test_simtel_event_source_on_gamma_test_one_event():
 
 def test_that_event_is_not_modified_after_loop():
 
-    dataset = prod5b_path
+    dataset = gamma_test_large_path
     with SimTelEventSource(input_url=dataset, max_events=2) as source:
         for event in source:
             last_event = copy.deepcopy(event)
@@ -64,11 +61,12 @@ def test_that_event_is_not_modified_after_loop():
 
 
 def test_additional_meta_data_from_simulation_config():
-    with SimTelEventSource(
-        input_url=gamma_test_large_path,
-        focal_length_choice='nominal',
-    ) as reader:
-        pass
+    with SimTelEventSource(input_url=gamma_test_large_path) as reader:
+        next(iter(reader))
+
+    # for expectation values
+    from astropy import units as u
+    from astropy.coordinates import Angle
 
     # There should be only one observation
     assert len(reader.obs_ids) == 1
@@ -106,10 +104,7 @@ def test_additional_meta_data_from_simulation_config():
 
 
 def test_properties():
-    source = SimTelEventSource(
-        input_url=gamma_test_large_path,
-        focal_length_choice='nominal',
-    )
+    source = SimTelEventSource(input_url=gamma_test_large_path)
 
     assert source.is_simulation
     assert source.datalevels == (DataLevel.R0, DataLevel.R1)
@@ -117,14 +112,11 @@ def test_properties():
     assert source.simulation_config[7514].corsika_version == 6990
 
 
-def test_gamma_file_prod2():
+def test_gamma_file():
     dataset = gamma_test_path
 
     with pytest.warns(UnknownPixelShapeWarning):
-        with SimTelEventSource(
-            input_url=dataset,
-            focal_length_choice='nominal',
-        ) as reader:
+        with SimTelEventSource(input_url=dataset) as reader:
             assert reader.is_compatible(dataset)
             assert reader.is_stream  # using gzip subprocess makes it a stream
 
@@ -142,9 +134,7 @@ def test_gamma_file_prod2():
 def test_max_events():
     max_events = 5
     with SimTelEventSource(
-        input_url=gamma_test_large_path,
-        max_events=max_events,
-        focal_length_choice='nominal',
+        input_url=gamma_test_large_path, max_events=max_events
     ) as reader:
         count = 0
         for _ in reader:
@@ -153,11 +143,7 @@ def test_max_events():
 
 
 def test_pointing():
-    with SimTelEventSource(
-        input_url=gamma_test_large_path,
-        max_events=3,
-        focal_length_choice='nominal',
-    ) as reader:
+    with SimTelEventSource(input_url=gamma_test_large_path, max_events=3) as reader:
         for e in reader:
             assert np.isclose(e.pointing.array_altitude.to_value(u.deg), 70)
             assert np.isclose(e.pointing.array_azimuth.to_value(u.deg), 0)
@@ -174,8 +160,7 @@ def test_allowed_telescopes():
     # test that the allowed_tels mask works:
     allowed_tels = {3, 4}
     with SimTelEventSource(
-        input_url=gamma_test_large_path, allowed_tels=allowed_tels, max_events=5,
-        focal_length_choice='nominal',
+        input_url=gamma_test_large_path, allowed_tels=allowed_tels, max_events=5
     ) as reader:
         assert not allowed_tels.symmetric_difference(reader.subarray.tel_ids)
         for event in reader:
@@ -203,8 +188,7 @@ def test_calibration_events():
         EventType.SUBARRAY,
     ]
     with SimTelEventSource(
-        input_url=calib_events_path, skip_calibration_events=False,
-        focal_length_choice='nominal',
+        input_url=calib_events_path, skip_calibration_events=False
     ) as reader:
 
         for event, expected_type in zip_longest(reader, expected_types):
@@ -213,10 +197,7 @@ def test_calibration_events():
 
 def test_trigger_times():
 
-    source = SimTelEventSource(
-        input_url=calib_events_path,
-        focal_length_choice='nominal',
-    )
+    source = SimTelEventSource(input_url=calib_events_path)
     t0 = Time("2020-05-06T15:30:00")
     t1 = Time("2020-05-06T15:40:00")
 
@@ -228,10 +209,7 @@ def test_trigger_times():
 
 
 def test_true_image():
-    with SimTelEventSource(
-        input_url=calib_events_path,
-        focal_length_choice='nominal',
-    ) as reader:
+    with SimTelEventSource(input_url=calib_events_path) as reader:
 
         for event in reader:
             for tel in event.simulation.tel.values():
@@ -240,10 +218,7 @@ def test_true_image():
 
 def test_instrument():
     """Test if same telescope types share a single instance of CameraGeometry"""
-    source = SimTelEventSource(
-        input_url=gamma_test_large_path,
-        focal_length_choice='nominal',
-    )
+    source = SimTelEventSource(input_url=gamma_test_large_path)
     subarray = source.subarray
     assert subarray.tel[1].optics.num_mirrors == 1
 
@@ -303,36 +278,39 @@ def test_apply_simtel_r1_calibration_2_channel():
     assert r1_waveforms[1, 0] == (r0_waveforms[0, 1, 0] - ped[0, 1]) * dc_to_pe[0, 1]
 
 
-def test_focal_length_choice():
-    # this file does not contain the effective focal length
-    with pytest.raises(RuntimeError):
-        SimTelEventSource(gamma_test_large_path)
-
-    with pytest.raises(RuntimeError):
-        SimTelEventSource(gamma_test_large_path, focal_length_choice='effective')
+def test_effective_focal_length():
+    test_file_url = (
+        "https://github.com/cta-observatory/pyeventio/raw/master/tests"
+        "/resources/prod4_pixelsettings_v3.gz"
+    )
+    test_file = download_file(test_file_url)
 
-    s = SimTelEventSource(gamma_test_large_path, focal_length_choice='nominal')
-    assert s.subarray.tel[1].optics.equivalent_focal_length == 28 * u.m
+    focal_length_nominal = 0
+    focal_length_effective = 0
 
-    # this file does
-    s = SimTelEventSource(prod5b_path, focal_length_choice='effective')
-    assert u.isclose(s.subarray.tel[1].optics.equivalent_focal_length, 29.3 * u.m, atol=0.05 * u.m)
-    # check guessing of the name is not affected by focal length choice
-    assert str(s.subarray.tel[1]) == 'LST_LST_LSTCam'
+    with SimTelEventSource(
+        input_url=test_file, focal_length_choice="nominal"
+    ) as source:
+        subarray = source.subarray
+        focal_length_nominal = subarray.tel[1].optics.equivalent_focal_length
 
-    s = SimTelEventSource(prod5b_path, focal_length_choice='nominal')
-    assert u.isclose(s.subarray.tel[1].optics.equivalent_focal_length, 28.0 * u.m, atol=0.05 * u.m)
-    # check guessing of the name is not affected by focal length choice
-    assert str(s.subarray.tel[1]) == 'LST_LST_LSTCam'
+    with SimTelEventSource(
+        input_url=test_file, focal_length_choice="effective"
+    ) as source:
+        subarray = source.subarray
+        focal_length_effective = subarray.tel[1].optics.equivalent_focal_length
 
+    assert focal_length_nominal > 0
+    assert focal_length_effective > 0
+    assert focal_length_nominal != focal_length_effective
 
 
 def test_only_config():
     config = Config()
-    config.SimTelEventSource.input_url = prod5b_path
+    config.SimTelEventSource.input_url = gamma_test_large_path
 
     s = SimTelEventSource(config=config)
-    assert s.input_url == Path(prod5b_path).absolute()
+    assert s.input_url == Path(gamma_test_large_path).absolute()
 
 
 def test_calibscale_and_calibshift(prod5_gamma_simtel_path):
@@ -377,17 +355,11 @@ def test_calibscale_and_calibshift(prod5_gamma_simtel_path):
 
 def test_true_image_sum():
     # this file does not contain true pe info
-    with SimTelEventSource(
-        gamma_test_large_path,
-        focal_length_choice='nominal',
-    ) as s:
+    with SimTelEventSource(gamma_test_large_path) as s:
         e = next(iter(s))
         assert np.all(np.isnan(sim.true_image_sum) for sim in e.simulation.tel.values())
 
-    with SimTelEventSource(
-        calib_events_path,
-        focal_length_choice='nominal',
-    ) as s:
+    with SimTelEventSource(calib_events_path) as s:
         e = next(iter(s))
 
         true_image_sums = {}
@@ -399,10 +371,8 @@ def test_true_image_sum():
 
     # check it also works with allowed_tels, since the values
     # are stored in a flat array in simtel
-    with SimTelEventSource(
-        calib_events_path, allowed_tels={2, 3},
-        focal_length_choice='nominal',
-    ) as s:
+    with SimTelEventSource(calib_events_path, allowed_tels={2, 3}) as s:
         e = next(iter(s))
+
         assert e.simulation.tel[2].true_image_sum == true_image_sums[2]
         assert e.simulation.tel[3].true_image_sum == true_image_sums[3]
diff --git a/ctapipe/reco/tests/test_HillasReconstructor.py b/ctapipe/reco/tests/test_HillasReconstructor.py
index 0b594cab..7ee4f1ad 100644
--- a/ctapipe/reco/tests/test_HillasReconstructor.py
+++ b/ctapipe/reco/tests/test_HillasReconstructor.py
@@ -197,11 +197,11 @@ def test_reconstruction_against_simulation(subarray_and_event_gamma_off_axis_500
 )
 def test_CameraFrame_against_TelescopeFrame(filename):
 
-    input_file = get_dataset_path(filename)
-        # "gamma_divergent_LaPalma_baseline_20Zd_180Az_prod3_test.simtel.gz"
-    # )
+    input_file = get_dataset_path(
+        "gamma_divergent_LaPalma_baseline_20Zd_180Az_prod3_test.simtel.gz"
+    )
 
-    source = SimTelEventSource(input_file, max_events=10, focal_length_choice="nominal")
+    source = SimTelEventSource(input_file, max_events=10)
 
     # too few events survive for this test with the defautl quality criteria,
     # use less restrictive ones
diff --git a/ctapipe/reco/tests/test_reconstruction_methods.py b/ctapipe/reco/tests/test_reconstruction_methods.py
index ec99c748..1989e396 100644
--- a/ctapipe/reco/tests/test_reconstruction_methods.py
+++ b/ctapipe/reco/tests/test_reconstruction_methods.py
@@ -30,7 +30,7 @@ def test_reconstructors(reconstructors):
         "gamma_LaPalma_baseline_20Zd_180Az_prod3b_test.simtel.gz"
     )
 
-    source = EventSource(filename, max_events=10, focal_length_choice="nominal")
+    source = EventSource(filename, max_events=10)
     subarray = source.subarray
     calib = CameraCalibrator(source.subarray)
     image_processor = ImageProcessor(source.subarray)
diff --git a/ctapipe/tools/tests/test_process.py b/ctapipe/tools/tests/test_process.py
index c9f4fbb5..d8f1a4b8 100644
--- a/ctapipe/tools/tests/test_process.py
+++ b/ctapipe/tools/tests/test_process.py
@@ -213,7 +213,6 @@ def test_stage_2_from_simtel(tmp_path):
                 f"--output={output}",
                 "--max-events=5",
                 "--overwrite",
-                "--SimTelEventSource.focal_length_choice=nominal",
             ],
             cwd=tmp_path,
         )
@@ -289,7 +288,6 @@ def test_training_from_simtel(tmp_path):
                 f"--output={output}",
                 "--max-events=5",
                 "--overwrite",
-                "--SimTelEventSource.focal_length_choice=nominal",
             ],
             cwd=tmp_path,
         )
diff --git a/ctapipe/tools/tests/test_tools.py b/ctapipe/tools/tests/test_tools.py
index ebf74a75..f906213b 100644
--- a/ctapipe/tools/tests/test_tools.py
+++ b/ctapipe/tools/tests/test_tools.py
@@ -13,7 +13,6 @@ from ctapipe.utils import get_dataset_path
 
 GAMMA_TEST_LARGE = get_dataset_path("gamma_test_large.simtel.gz")
 LST_MUONS = get_dataset_path("lst_muons.simtel.zst")
-PROD5B_PATH = get_dataset_path("gamma_20deg_0deg_run2___cta-prod5-paranal_desert-2147m-Paranal-dark_cone10-100evts.simtel.zst")
 
 
 def test_muon_reconstruction_simtel(tmp_path):
@@ -26,7 +25,6 @@ def test_muon_reconstruction_simtel(tmp_path):
             argv=[
                 f"--input={LST_MUONS}",
                 f"--output={muon_simtel_output_file}",
-                "--SimTelEventSource.focal_length_choice=nominal",
                 "--overwrite",
             ],
             cwd=tmp_path,
@@ -73,12 +71,7 @@ def test_display_dl1(tmp_path, dl1_image_file, dl1_parameters_file):
     # test simtel
     assert (
         run_tool(
-            DisplayDL1Calib(),
-            argv=[
-                "--max-events=1", "--telescope=11",
-                "--SimTelEventSource.focal_length_choice=nominal",
-            ],
-            cwd=tmp_path
+            DisplayDL1Calib(), argv=["--max-events=1", "--telescope=11"], cwd=tmp_path
         )
         == 0
     )
@@ -132,7 +125,7 @@ def test_dump_triggers(tmp_path):
 
     sys.argv = ["dump_triggers"]
     outfile = tmp_path / "triggers.fits"
-    tool = DumpTriggersTool(infile=PROD5B_PATH, outfile=str(outfile))
+    tool = DumpTriggersTool(infile=GAMMA_TEST_LARGE, outfile=str(outfile))
 
     assert run_tool(tool, cwd=tmp_path) == 0
 
@@ -146,18 +139,18 @@ def test_dump_instrument(tmp_path):
     sys.argv = ["dump_instrument"]
     tool = DumpInstrumentTool()
 
-    assert run_tool(tool, [f"--input={PROD5B_PATH}"], cwd=tmp_path) == 0
+    assert run_tool(tool, [f"--input={GAMMA_TEST_LARGE}"], cwd=tmp_path) == 0
     assert (tmp_path / "FlashCam.camgeom.fits.gz").exists()
 
     assert (
-        run_tool(tool, [f"--input={PROD5B_PATH}", "--format=ecsv"], cwd=tmp_path)
+        run_tool(tool, [f"--input={GAMMA_TEST_LARGE}", "--format=ecsv"], cwd=tmp_path)
         == 0
     )
 
     assert (tmp_path / "MonteCarloArray.optics.ecsv").exists()
 
     assert (
-        run_tool(tool, [f"--input={PROD5B_PATH}", "--format=hdf5"], cwd=tmp_path)
+        run_tool(tool, [f"--input={GAMMA_TEST_LARGE}", "--format=hdf5"], cwd=tmp_path)
         == 0
     )
     assert (tmp_path / "subarray.h5").exists()