@@ -131,9 +131,9 @@ def _pad_volume(
131131>>> image.plot(cmap="gray")
132132
133133"""
134-
134+ from __future__ import annotations
135135from pint import Quantity
136- from typing import Any , Dict , List , Tuple , Union
136+ from typing import Any , Dict , List , Tuple
137137from deeptrack .backend .units import (
138138 ConversionTable ,
139139 create_context ,
@@ -143,15 +143,15 @@ def _pad_volume(
143143from deeptrack .math import AveragePooling
144144from deeptrack .features import propagate_data_to_dependencies
145145import numpy as np
146- from .features import DummyFeature , Feature , StructuralFeature
147- from .image import Image , pad_image_to_fft , maybe_cupy
148- from .types import ArrayLike , PropertyLike
149- from .backend ._config import cupy
146+ from deeptrack .features import DummyFeature , Feature , StructuralFeature
147+ from deeptrack .image import Image , pad_image_to_fft , maybe_cupy
148+ from deeptrack .types import ArrayLike , PropertyLike
149+ from deeptrack .backend ._config import cupy
150150from scipy .ndimage import convolve
151151import warnings
152152
153153from . import units as u
154- from .backend import config
154+ from deeptrack .backend import config
155155from deeptrack import image
156156
157157
@@ -203,7 +203,7 @@ class Microscope(StructuralFeature):
203203 __distributed__ = False
204204
205205 def __init__ (
206- self : ' Microscope' ,
206+ self : Microscope ,
207207 sample : Feature ,
208208 objective : Feature ,
209209 ** kwargs : Dict [str , Any ],
@@ -235,8 +235,8 @@ def __init__(
235235 self ._sample .store_properties ()
236236
237237 def get (
238- self : ' Microscope' ,
239- image : Union [ Image , None ] ,
238+ self : Microscope ,
239+ image : Image | None ,
240240 ** kwargs : Dict [str , Any ],
241241 ) -> Image :
242242 """Generate an image of the sample using the defined optical system.
@@ -246,7 +246,7 @@ def get(
246246
247247 Parameters
248248 ----------
249- image: Union[ Image, None]
249+ image: Image | None
250250 The input image to be processed. If None, a new image is created.
251251 **kwargs: Dict[str, Any]
252252 Additional parameters for the imaging process.
@@ -480,11 +480,11 @@ class Optics(Feature):
480480 )
481481
482482 def __init__ (
483- self : ' Optics' ,
483+ self : Optics ,
484484 NA : PropertyLike [float ] = 0.7 ,
485485 wavelength : PropertyLike [float ] = 0.66e-6 ,
486486 magnification : PropertyLike [float ] = 10 ,
487- resolution : PropertyLike [Union [ float , ArrayLike [float ] ]] = 1e-6 ,
487+ resolution : PropertyLike [float | ArrayLike [float ]] = 1e-6 ,
488488 refractive_index_medium : PropertyLike [float ] = 1.33 ,
489489 padding : PropertyLike [ArrayLike [int ]] = (10 , 10 , 10 , 10 ),
490490 output_region : PropertyLike [ArrayLike [int ]] = (0 , 0 , 128 , 128 ),
@@ -563,7 +563,7 @@ def __init__(
563563 """
564564
565565 def get_voxel_size (
566- resolution : Union [ float , ArrayLike [float ] ],
566+ resolution : float | ArrayLike [float ],
567567 magnification : float ,
568568 ) -> ArrayLike [float ]:
569569 """ Calculate the voxel size.
@@ -587,7 +587,7 @@ def get_voxel_size(
587587 return np .ones ((3 ,)) * props ["resolution" ] / props ["magnification" ]
588588
589589 def get_pixel_size (
590- resolution : Union [ float , ArrayLike [float ] ],
590+ resolution : float | ArrayLike [float ],
591591 magnification : float ,
592592 ) -> float :
593593 """ Calculate the pixel size.
@@ -641,8 +641,8 @@ def get_pixel_size(
641641 )
642642
643643 def _process_properties (
644- self : ' Optics' ,
645- propertydict : Dict [str , Any ],
644+ self : Optics ,
645+ propertydict : Dict [str , Any ],
646646 ) -> Dict [str , Any ]:
647647 """Processes and validates the input properties.
648648
@@ -681,13 +681,13 @@ def _process_properties(
681681 return propertydict
682682
683683 def _pupil (
684- self : ' Optics' ,
684+ self : Optics ,
685685 shape : ArrayLike [int ],
686686 NA : float ,
687687 wavelength : float ,
688688 refractive_index_medium : float ,
689689 include_aberration : bool = True ,
690- defocus : Union [ float , ArrayLike [float ] ] = 0 ,
690+ defocus : float | ArrayLike [float ] = 0 ,
691691 ** kwargs : Dict [str , Any ],
692692 ):
693693 """Calculates the pupil function at different focal points.
@@ -787,7 +787,7 @@ def _pupil(
787787 return pupil_functions
788788
789789 def _pad_volume (
790- self : ' Optics' ,
790+ self : Optics ,
791791 volume : ArrayLike [complex ],
792792 limits : ArrayLike [int ] = None ,
793793 padding : ArrayLike [int ] = None ,
@@ -884,7 +884,7 @@ def _pad_volume(
884884 return new_volume , new_limits
885885
886886 def __call__ (
887- self : ' Optics' ,
887+ self : Optics ,
888888 sample : Feature ,
889889 ** kwargs : Dict [str , Any ],
890890 ) -> Microscope :
@@ -915,7 +915,16 @@ def __call__(
915915 True
916916
917917 """
918-
918+ from deeptrack .scatterers import MieScatterer # Temporary place for this import.
919+
920+ if isinstance (self , (Darkfield , ISCAT , Holography )) and not isinstance (sample , MieScatterer ):
921+ warnings .warn (
922+ f"{ type (self ).__name__ } optics must be used with Mie scatterers "
923+ f"to produce a { type (self ).__name__ } image. "
924+ f"Got sample of type { type (sample ).__name__ } ." ,
925+ UserWarning
926+ )
927+
919928 return Microscope (sample , self , ** kwargs )
920929
921930 # def _no_wrap_format_input(self, *args, **kwargs) -> list:
@@ -1013,7 +1022,7 @@ class Fluorescence(Optics):
10131022 __gpu_compatible__ = True
10141023
10151024 def get (
1016- self : ' Fluorescence' ,
1025+ self : Fluorescence ,
10171026 illuminated_volume : ArrayLike [complex ],
10181027 limits : ArrayLike [int ],
10191028 ** kwargs : Dict [str , Any ]
@@ -1246,7 +1255,7 @@ class Brightfield(Optics):
12461255 )
12471256
12481257 def get (
1249- self : ' Brightfield' ,
1258+ self : Brightfield ,
12501259 illuminated_volume : ArrayLike [complex ],
12511260 limits : ArrayLike [int ],
12521261 fields : ArrayLike [complex ],
@@ -1504,7 +1513,7 @@ class ISCAT(Brightfield):
15041513 """
15051514
15061515 def __init__ (
1507- self : ' ISCAT' ,
1516+ self : ISCAT ,
15081517 illumination_angle : float = np .pi ,
15091518 amp_factor : float = 1 ,
15101519 ** kwargs : Dict [str , Any ],
@@ -1592,7 +1601,7 @@ class Darkfield(Brightfield):
15921601 """
15931602
15941603 def __init__ (
1595- self : ' Darkfield' ,
1604+ self : Darkfield ,
15961605 illumination_angle : float = np .pi / 2 ,
15971606 ** kwargs : Dict [str , Any ]
15981607 ) -> None :
@@ -1613,7 +1622,7 @@ def __init__(
16131622
16141623 #Retrieve get as super
16151624 def get (
1616- self : ' Darkfield' ,
1625+ self : Darkfield ,
16171626 illuminated_volume : ArrayLike [complex ],
16181627 limits : ArrayLike [int ],
16191628 fields : ArrayLike [complex ],
@@ -1693,7 +1702,7 @@ class IlluminationGradient(Feature):
16931702 """
16941703
16951704 def __init__ (
1696- self : ' IlluminationGradient' ,
1705+ self : IlluminationGradient ,
16971706 gradient : PropertyLike [ArrayLike [float ]] = (0 , 0 ),
16981707 constant : PropertyLike [float ] = 0 ,
16991708 vmin : PropertyLike [float ] = 0 ,
@@ -1725,7 +1734,7 @@ def __init__(
17251734 )
17261735
17271736 def get (
1728- self : ' IlluminationGradient' ,
1737+ self : IlluminationGradient ,
17291738 image : ArrayLike [complex ],
17301739 gradient : ArrayLike [float ],
17311740 constant : float ,
@@ -1787,7 +1796,7 @@ def get(
17871796
17881797
17891798def _get_position (
1790- image : Image ,
1799+ image : Image ,
17911800 mode : str = "corner" ,
17921801 return_z : bool = False ,
17931802) -> np .ndarray :
@@ -2033,4 +2042,4 @@ def _create_volume(
20332042 int (within_volume_position [2 ]) :
20342043 int (within_volume_position [2 ] + shape [2 ]),
20352044 ] += scatterer
2036- return volume , limits
2045+ return volume , limits
0 commit comments