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.
def copy_ray(self):
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)

Returns a new OpticalRay object with the same properties.