ModuleOpticalRay
class
Ray:
13class Ray: 14 """ 15 Represents an optical ray from geometrical optics. 16 """ 17 18 # __slots__ = ('_point', '_vector', '_path', '_number', '_wavelength', '_incidence', '_intensity') #doesn't bring a significant performance improvement 19 20 def __init__( 21 self, 22 Point: np.ndarray, 23 Vector: np.ndarray, 24 Path=(0.0,), 25 Number=None, 26 Wavelength=None, 27 Incidence=None, 28 Intensity=None, 29 ): 30 """ 31 Parameters 32 ---------- 33 Point : np.ndarray 34 Point source of the ray.. 35 36 Vector : np.ndarray 37 Direction unit-vector of the ray.. 38 39 Path : List of floats, optional TODO correct considering update to list 40 Path length in mm covered by ray *before* its starting Point. The default is 0. 41 42 Number : int, optional 43 Index needed to link the incident ray and the reflected ray. The default is None, but it should be set by afterwards setting the attribute Ray._number.! 44 45 Wavelength : float, optional 46 Wavelength of the light in mm. The default is None. 47 48 Incidence : float, optional 49 Incidence angle in radian of the ray on the optical element *from which it originates*. 50 Gets calculated during ray tracing. The default is None. The source rays therefore have "None" incidence. 51 52 Intensity : float, optional 53 Intensity, or more strictly speaking the fluence fraction in arb.u. carried by the ray. The default is None. 54 55 """ 56 self.point = Point # the setter checks 57 self.vector = Vector # the setter checks and normalizes 58 self._path = Path 59 self._wavelength = Wavelength 60 self._incidence = Incidence 61 self._intensity = Intensity 62 if type(Number) == int or Number is None: 63 self._number = Number 64 else: 65 raise TypeError("Ray Number must be an integer.") 66 67 """ 68 Removing the setters and getters with their checks would gain about 10-30% speed because we use the Ray-class a lot. 69 Then the main risk seems that we can no longer trust in the vector being a unit vector. 70 """ 71 72 @property 73 def point(self): 74 return self._point 75 76 @point.setter 77 def point(self, Point): 78 if type(Point) == np.ndarray and len(Point) == 3: 79 self._point = Point 80 else: 81 raise TypeError("Ray Point must be a 3D numpy.ndarray, but it is %s." % type(Point)) 82 83 @property 84 def vector(self): 85 return self._vector 86 87 @vector.setter 88 def vector(self, Vector): 89 if type(Vector) == np.ndarray and len(Vector) == 3 and np.linalg.norm(Vector) > 1e-9: 90 self._vector = Vector / np.linalg.norm(Vector) 91 else: 92 raise TypeError("Ray Vector must be a 3D numpy.ndarray with finite length.") 93 94 @property 95 def path(self): 96 return self._path 97 98 @path.setter 99 def path(self, Path): 100 self._path = Path 101 102 @property 103 def number(self): 104 return self._number 105 106 # actually, we don't want to number to be changable afterwards, so not setter 107 # @number.setter 108 # def number(self, Number): 109 # if type(Number) == int or Number is None: 110 # self._number = Number 111 # else: raise TypeError('Ray Number must be an integer.') 112 113 @property 114 def wavelength(self): 115 return self._wavelength 116 117 @wavelength.setter 118 def wavelength(self, Wavelength): 119 if type(Wavelength) in [int, float, np.float64]: 120 self._wavelength = Wavelength 121 else: 122 raise TypeError("Ray Wavelength must be int or float or None.") 123 124 @property 125 def incidence(self): 126 return self._incidence 127 128 @incidence.setter 129 def incidence(self, Incidence): 130 if type(Incidence) in [float, np.float64]: 131 self._incidence = Incidence 132 else: 133 raise TypeError("Ray Incidence must be a float or None.") 134 135 @property 136 def intensity(self): 137 return self._intensity 138 139 @intensity.setter 140 def intensity(self, Intensity): 141 if type(Intensity) in [int, float, np.float64]: 142 self._intensity = Intensity 143 else: 144 raise TypeError("Ray Intensity must be int or float or None.") 145 146 # %% 147 def copy_ray(self): 148 """ 149 Returns a new OpticalRay object with the same properties. 150 """ 151 return Ray(self.point, self.vector, self.path, self.number, self.wavelength, self.incidence, self.intensity) 152 153 def __hash__(self): 154 point_tuple = tuple(self.point.reshape(1, -1)[0]) 155 vector_tuple = tuple(self.vector.reshape(1, -1)[0]) 156 return hash( 157 point_tuple + vector_tuple + (self.path, self.number, self.wavelength, self.incidence, self.intensity) 158 )
Represents an optical ray from geometrical optics.
Ray( Point: numpy.ndarray, Vector: numpy.ndarray, Path=(0.0,), Number=None, Wavelength=None, Incidence=None, Intensity=None)
20 def __init__( 21 self, 22 Point: np.ndarray, 23 Vector: np.ndarray, 24 Path=(0.0,), 25 Number=None, 26 Wavelength=None, 27 Incidence=None, 28 Intensity=None, 29 ): 30 """ 31 Parameters 32 ---------- 33 Point : np.ndarray 34 Point source of the ray.. 35 36 Vector : np.ndarray 37 Direction unit-vector of the ray.. 38 39 Path : List of floats, optional TODO correct considering update to list 40 Path length in mm covered by ray *before* its starting Point. The default is 0. 41 42 Number : int, optional 43 Index needed to link the incident ray and the reflected ray. The default is None, but it should be set by afterwards setting the attribute Ray._number.! 44 45 Wavelength : float, optional 46 Wavelength of the light in mm. The default is None. 47 48 Incidence : float, optional 49 Incidence angle in radian of the ray on the optical element *from which it originates*. 50 Gets calculated during ray tracing. The default is None. The source rays therefore have "None" incidence. 51 52 Intensity : float, optional 53 Intensity, or more strictly speaking the fluence fraction in arb.u. carried by the ray. The default is None. 54 55 """ 56 self.point = Point # the setter checks 57 self.vector = Vector # the setter checks and normalizes 58 self._path = Path 59 self._wavelength = Wavelength 60 self._incidence = Incidence 61 self._intensity = Intensity 62 if type(Number) == int or Number is None: 63 self._number = Number 64 else: 65 raise TypeError("Ray Number must be an integer.")
Parameters
Point : np.ndarray
Point source of the ray..
Vector : np.ndarray
Direction unit-vector of the ray..
Path : List of floats, optional TODO correct considering update to list
Path length in mm covered by ray *before* its starting Point. The default is 0.
Number : int, optional
Index needed to link the incident ray and the reflected ray. The default is None, but it should be set by afterwards setting the attribute Ray._number.!
Wavelength : float, optional
Wavelength of the light in mm. The default is None.
Incidence : float, optional
Incidence angle in radian of the ray on the optical element *from which it originates*.
Gets calculated during ray tracing. The default is None. The source rays therefore have "None" incidence.
Intensity : float, optional
Intensity, or more strictly speaking the fluence fraction in arb.u. carried by the ray. The default is None.
Last modified April 8, 2024: Merge pull request #11 from mightymightys/dev (60da018)