diff --git a/raytracing/imagingpath.py b/raytracing/imagingpath.py
index b9ee7de..eaea927 100644
--- a/raytracing/imagingpath.py
+++ b/raytracing/imagingpath.py
@@ -188,7 +188,6 @@ class ImagingPath(MatrixGroup):
         """
         return self.chiefRay(y=None)
 
-
     def marginalRays(self, y=0):
         """This function calculates the marginal rays for a height y at object.
         The marginal rays for height y are the rays that hit the upper and lower
@@ -256,6 +255,9 @@ class ImagingPath(MatrixGroup):
 
         """
         (stopPosition, stopDiameter) = self.apertureStop()
+        if stopPosition is None:
+            return None  # No aperture stop -> no marginal rays
+
         transferMatrixToApertureStop = self.transferMatrix(upTo=stopPosition)
         A = transferMatrixToApertureStop.A
         B = transferMatrixToApertureStop.B
@@ -687,10 +689,10 @@ class ImagingPath(MatrixGroup):
         display range : 7
 
         """
-        
+
         displayRange = self.largestDiameter
-        if displayRange == float('+Inf') or displayRange <= 2*self.objectHeight:
-            displayRange = 2*self.objectHeight
+        if displayRange == float('+Inf') or displayRange <= 2 * self.objectHeight:
+            displayRange = 2 * self.objectHeight
 
         conjugates = self.intermediateConjugates()
         if len(conjugates) != 0:
@@ -982,7 +984,7 @@ class ImagingPath(MatrixGroup):
         arrowHeadHeight = self.objectHeight * 0.1
 
         heightFactor = self.objectHeight / yScaling
-        arrowHeadWidth = xScaling * 0.01 * (heightFactor/0.2) ** (3/4)
+        arrowHeadWidth = xScaling * 0.01 * (heightFactor / 0.2) ** (3 / 4)
 
         axes.arrow(
             self.objectPosition,
@@ -1015,7 +1017,7 @@ class ImagingPath(MatrixGroup):
             arrowHeadHeight = arrowHeight * 0.1
 
             heightFactor = arrowHeight / yScaling
-            arrowHeadWidth = xScaling * 0.01 * (heightFactor/0.2) ** (3/4)
+            arrowHeadWidth = xScaling * 0.01 * (heightFactor / 0.2) ** (3 / 4)
 
             axes.arrow(
                 imagePosition,
@@ -1086,7 +1088,7 @@ class ImagingPath(MatrixGroup):
             center = z + pupilPosition
             (xScaling, yScaling) = self.axesToDataScale(axes)
             heightFactor = halfHeight * 2 / yScaling
-            width = xScaling * 0.01 / 2 * (heightFactor/0.2) ** (3/4)
+            width = xScaling * 0.01 / 2 * (heightFactor / 0.2) ** (3 / 4)
 
             axes.add_patch(patches.Polygon(
                 [[center - width, halfHeight],

ImagingPath: marginalRays raises exception when no apertureStop
When we want the marginal rays of an `ImagingPath` that has no aperture stop, a `TypeError` is raised. Example:

```python
path = ImagingPath(System4f(10, 10))
path.marginalRays() # Raises TypeError, no field stop
```
diff --git a/raytracing/tests/testsImagingPath.py b/raytracing/tests/testsImagingPath.py
index be8f0e1..6590fe8 100644
--- a/raytracing/tests/testsImagingPath.py
+++ b/raytracing/tests/testsImagingPath.py
@@ -61,6 +61,10 @@ class TestImagingPath(unittest.TestCase):
         chiefRay = path.chiefRay()
         self.assertIsNone(chiefRay)
 
+    def testMarginalRaysNoApertureStop(self):
+        path = ImagingPath(System4f(10, 10))
+        self.assertIsNone(path.marginalRays())
+
     def testMarginalRaysIsImaging(self):
         path = ImagingPath(System4f(10, 10))
         path.append(Aperture(10))

pip install -e .[dev]
parse_log_pytest
numpy>=1.16.0 matplotlib
pytest
apt-get update apt-get install -y gcc
3.9
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
Brotli @ file:///croot/brotli-split_1736182456865/work
contourpy @ file:///croot/contourpy_1738160616259/work
cycler @ file:///tmp/build/80754af9/cycler_1637851556182/work
exceptiongroup==1.2.2
fonttools @ file:///croot/fonttools_1737039080035/work
importlib_resources @ file:///croot/importlib_resources-suite_1720641103994/work
iniconfig==2.1.0
kiwisolver @ file:///croot/kiwisolver_1672387140495/work
matplotlib==3.9.2
numpy @ file:///croot/numpy_and_numpy_base_1736283260865/work/dist/numpy-2.0.2-cp39-cp39-linux_x86_64.whl#sha256=3387e3e62932fa288bc18e8f445ce19e998b418a65ed2064dd40a054f976a6c7
packaging @ file:///croot/packaging_1734472117206/work
pillow @ file:///croot/pillow_1738010226202/work
pluggy==1.5.0
pyparsing @ file:///croot/pyparsing_1731445506121/work
PyQt6==6.7.1
PyQt6_sip @ file:///croot/pyqt-split_1740498191142/work/pyqt_sip
pytest==8.3.5
python-dateutil @ file:///croot/python-dateutil_1716495738603/work
-e git+https://github.com/DCC-Lab/RayTracing.git@2c3d3f64b5aa09fc0a45a2422fe8bef834972b0b#egg=raytracing
sip @ file:///croot/sip_1738856193618/work
six @ file:///tmp/build/80754af9/six_1644875935023/work
tomli @ file:///opt/conda/conda-bld/tomli_1657175507142/work
tornado @ file:///croot/tornado_1733960490606/work
unicodedata2 @ file:///croot/unicodedata2_1736541023050/work
zipp @ file:///croot/zipp_1732630741423/work

name: RayTracing
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
  - blas=1.0=openblas
  - brotli-python=1.0.9=py39h6a678d5_9
  - bzip2=1.0.8=h5eee18b_6
  - c-ares=1.19.1=h5eee18b_0
  - ca-certificates=2025.2.25=h06a4308_0
  - contourpy=1.2.1=py39hdb19cb5_1
  - cycler=0.11.0=pyhd3eb1b0_0
  - cyrus-sasl=2.1.28=h52b45da_1
  - expat=2.6.4=h6a678d5_0
  - fontconfig=2.14.1=h55d465d_3
  - fonttools=4.55.3=py39h5eee18b_0
  - freetype=2.12.1=h4a9f257_0
  - icu=73.1=h6a678d5_0
  - importlib_resources=6.4.0=py39h06a4308_0
  - jpeg=9e=h5eee18b_3
  - kiwisolver=1.4.4=py39h6a678d5_0
  - krb5=1.20.1=h143b758_1
  - lcms2=2.16=hb9589c4_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - lerc=4.0.0=h6a678d5_0
  - libabseil=20250127.0=cxx17_h6a678d5_0
  - libcups=2.4.2=h2d74bed_1
  - libcurl=8.12.1=hc9e6f67_0
  - libdeflate=1.22=h5eee18b_0
  - libedit=3.1.20230828=h5eee18b_0
  - libev=4.33=h7f8727e_1
  - libffi=3.4.4=h6a678d5_1
  - libgcc-ng=11.2.0=h1234567_1
  - libgfortran-ng=11.2.0=h00389a5_1
  - libgfortran5=11.2.0=h1234567_1
  - libglib=2.78.4=hdc74915_0
  - libgomp=11.2.0=h1234567_1
  - libiconv=1.16=h5eee18b_3
  - libnghttp2=1.57.0=h2d74bed_0
  - libopenblas=0.3.21=h043d6bf_0
  - libpng=1.6.39=h5eee18b_0
  - libpq=17.4=hdbd6064_0
  - libprotobuf=5.29.3=hc99497a_0
  - libssh2=1.11.1=h251f7ec_0
  - libstdcxx-ng=11.2.0=h1234567_1
  - libtiff=4.5.1=hffd6297_1
  - libuuid=1.41.5=h5eee18b_0
  - libwebp-base=1.3.2=h5eee18b_1
  - libxcb=1.15=h7f8727e_0
  - libxkbcommon=1.0.1=h097e994_2
  - libxml2=2.13.5=hfdd30dd_0
  - lz4-c=1.9.4=h6a678d5_1
  - matplotlib=3.9.2=py39h06a4308_1
  - matplotlib-base=3.9.2=py39hbfdbfaf_1
  - mysql=8.4.0=h721767e_2
  - ncurses=6.4=h6a678d5_0
  - numpy=2.0.2=py39heeff2f4_0
  - numpy-base=2.0.2=py39h8a23956_0
  - openjpeg=2.5.2=he7f1fd0_0
  - openldap=2.6.4=h42fbc30_0
  - openssl=3.0.16=h5eee18b_0
  - packaging=24.2=py39h06a4308_0
  - pcre2=10.42=hebb0a14_1
  - pillow=11.1.0=py39hcea889d_0
  - pip=25.0=py39h06a4308_0
  - pyparsing=3.2.0=py39h06a4308_0
  - pyqt=6.7.1=py39h6a678d5_0
  - pyqt6-sip=13.9.1=py39h5eee18b_0
  - python=3.9.21=he870216_1
  - python-dateutil=2.9.0post0=py39h06a4308_2
  - qtbase=6.7.3=hdaa5aa8_0
  - qtdeclarative=6.7.3=h6a678d5_0
  - qtsvg=6.7.3=he621ea3_0
  - qttools=6.7.3=h80c7b02_0
  - qtwebchannel=6.7.3=h6a678d5_0
  - qtwebsockets=6.7.3=h6a678d5_0
  - readline=8.2=h5eee18b_0
  - setuptools=72.1.0=py39h06a4308_0
  - sip=6.10.0=py39h6a678d5_0
  - six=1.16.0=pyhd3eb1b0_1
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - tomli=2.0.1=py39h06a4308_0
  - tornado=6.4.2=py39h5eee18b_0
  - tzdata=2025a=h04d1e81_0
  - unicodedata2=15.1.0=py39h5eee18b_1
  - wheel=0.45.1=py39h06a4308_0
  - xcb-util-cursor=0.1.4=h5eee18b_0
  - xz=5.6.4=h5eee18b_1
  - zipp=3.21.0=py39h06a4308_0
  - zlib=1.2.13=h5eee18b_1
  - zstd=1.5.6=hc292b87_0
  - pip:
      - exceptiongroup==1.2.2
      - iniconfig==2.1.0
      - pluggy==1.5.0
      - pytest==8.3.5
prefix: /opt/conda/envs/RayTracing

raytracing/tests/testsImagingPath.py::TestImagingPath::testMarginalRaysNoApertureStop
raytracing/tests/testsImagingPath.py::TestImagingPath::testChiefRayNoApertureStop raytracing/tests/testsImagingPath.py::TestImagingPath::testDisplayRangeWithEmptyPath raytracing/tests/testsImagingPath.py::TestImagingPath::testDisplayRangeWithFiniteLens raytracing/tests/testsImagingPath.py::TestImagingPath::testDisplayRangeWithObjectHigherThanLens raytracing/tests/testsImagingPath.py::TestImagingPath::testEntrancePupilAIs0 raytracing/tests/testsImagingPath.py::TestImagingPath::testImageSizeDIs0 raytracing/tests/testsImagingPath.py::TestImagingPath::testImagingPathInfiniteFieldOfView raytracing/tests/testsImagingPath.py::TestImagingPath::testImagingPathInfiniteFieldOfView2 raytracing/tests/testsImagingPath.py::TestImagingPath::testImagingPathInfiniteFieldOfView3 raytracing/tests/testsImagingPath.py::TestImagingPath::testMarginalRaysIsImaging
raytracing/imagingpath.py
raytracing/imagingpath.py