ModuleSource

Provides a definition of sources of light. A source can be either a composite source (a sum of sources) or a simple source. A simple source is defined by 4 parameters:

  • Wavelength (monochromatic)
  • Angular power distribution
  • Ray origins distribution
  • Ray directions distribution A reason to use composite sources is for when the power and ray distributions depend on the wavelength. Another source option is the source containing just a list of rays that can be prepared manually. Finally another source option is one used for alignment, containing a single ray.

Created in 2019

@author: Anthony Guillaume and Stefan Haessler

  1"""
  2Provides a definition of sources of light.
  3A source can be either a composite source (a sum of sources) or a simple source.
  4A simple source is defined by 4 parameters:
  5- Wavelength (monochromatic)
  6- Angular power distribution
  7- Ray origins distribution
  8- Ray directions distribution
  9A reason to use composite sources is for when the power and ray distributions depend on the wavelength.
 10Another source option is the source containing just a list of rays that can be prepared manually.
 11Finally another source option is one used for alignment, containing a single ray.
 12
 13
 14Created in 2019
 15
 16@author: Anthony Guillaume and Stefan Haessler
 17"""
 18
 19# %% Modules
 20import ARTcore.ModuleOpticalRay as mray
 21import ARTcore.ModuleGeometry as mgeo
 22import ARTcore.ModuleProcessing as mp
 23
 24from ARTcore.DepGraphDefinitions import UniformSpectraCalculator
 25
 26import numpy as np
 27from abc import ABC, abstractmethod
 28import logging
 29
 30logger = logging.getLogger(__name__)
 31
 32# %% Abstract base classes for sources
 33class Source(ABC):
 34    """
 35    Abstract base class for sources.
 36    Fundamentally a source just has to be able to return a list of rays.
 37    To do so, we make it callable.
 38    """
 39    @abstractmethod
 40    def __call__(self,N):
 41        pass
 42
 43class PowerDistribution(ABC):
 44    """
 45    Abstract base class for angular power distributions.
 46    """
 47    @abstractmethod
 48    def __call__(self, Origins, Directions):
 49        """
 50        Return the power of the rays coming 
 51        from the origin points Origins to the directions Directions.
 52        """
 53        pass
 54class RayOriginsDistribution(ABC):
 55    """
 56    Abstract base class for ray origins distributions.
 57    """
 58    @abstractmethod
 59    def __call__(self, N):
 60        """
 61        Return the origins of N rays.
 62        """
 63        pass
 64
 65class RayDirectionsDistribution(ABC):
 66    """
 67    Abstract base class for ray directions distributions.
 68    """
 69    @abstractmethod
 70    def __call__(self, N):
 71        """
 72        Return the directions of N rays.
 73        """
 74        pass
 75
 76class Spectrum(ABC):
 77    """
 78    Abstract base class for spectra.
 79    """
 80    @abstractmethod
 81    def __call__(self, N):
 82        """
 83        Return the wavelengths of N rays.
 84        """
 85        pass
 86
 87# %% Specific power distributions
 88class SpatialGaussianPowerDistribution(PowerDistribution):
 89    """
 90    Spatial Gaussian power distribution, depending only on ray origin points, and not on directions. 
 91    
 92    Attributes
 93    ----------
 94        Power : float
 95            Peak power of the distribution in arbitrary units (user can keep track of their own units.)
 96
 97        W0 : float
 98            1/e^2 beam waist in mm     
 99    """
100    def __init__(self, Power, W0):
101        self.Power = Power
102        self.W0 = W0
103
104    def __call__(self, Origins, Directions):
105        """
106        Return the power of the rays coming 
107        from the origin points Origins to the directions Directions.
108        
109        Parameters
110        ----------
111            Origins : mgeo.PointArray 
112               PointArray as defined in ModuleGeometry, with points of origin of the rays.
113
114            Directions : mgeo.VectorArray
115                VectorArray as defined in ModuleGeometry, with ray vectors.
116
117        Returns
118        -------
119            Powers: numpy.array
120                Array of powers for each ray.
121        
122        """
123        return self.Power * np.exp(-2 * np.linalg.norm(Origins, axis=1) ** 2 / self.W0 ** 2)
124    
125class AngularGaussianPowerDistribution(PowerDistribution):
126    """
127    Angular Gaussian power distribution, depending only on ray directions, but not origin points. 
128    
129    Attributes
130    ----------
131        Power : float
132            Peak power of the distribution in arbitrary units (user can keep track of their own units.)
133
134        Divergence : float
135            1/e^2 divergence half-angle in radians.
136    """
137    def __init__(self, Power, Divergence):
138        self.Power = Power
139        self.Divergence = Divergence
140
141    def __call__(self, Origins, Directions):
142        """
143        Return the power of the rays coming 
144        from the origin points Origins to the directions Directions.
145        
146        Parameters
147        ----------
148            Origins : mgeo.PointArray 
149               PointArray as defined in ModuleGeometry, with points of origin of the rays.
150
151            Directions : mgeo.VectorArray
152                VectorArray as defined in ModuleGeometry, with ray vectors.
153
154        Returns
155        -------
156            Powers: numpy.array
157                Array of powers for each ray.
158        
159        """
160        return self.Power * np.exp(-2 * np.arccos(np.dot(Directions, [0, 0, 1])) ** 2 / self.Divergence ** 2)
161
162class GaussianPowerDistribution(PowerDistribution):
163    """
164    Gaussian power distribution, depending on ray origin points and directions.
165    
166    Attributes
167    ----------
168        Power : float
169            Peak power of the distribution in arbitrary units (user can keep track of their own units.)
170
171        W0 : float
172            1/e^2 beam waist in mm            
173
174        Divergence : float
175            1/e^2 divergence half-angle in radians.
176    """
177    def __init__(self, Power, W0, Divergence):
178        self.Power = Power
179        self.W0 = W0
180        self.Divergence = Divergence
181
182    def __call__(self, Origins, Directions):
183        """
184        Return the power of the rays coming 
185        from the origin points Origins to the directions Directions.
186        
187        Parameters
188        ----------
189            Origins : mgeo.PointArray 
190               PointArray as defined in ModuleGeometry, with points of origin of the rays.
191
192            Directions : mgeo.VectorArray
193                VectorArray as defined in ModuleGeometry, with ray vectors.
194
195        Returns
196        -------
197            Powers: numpy.array
198                Array of powers for each ray.
199        
200        """
201        return self.Power * np.exp(-2 * (Origins-mgeo.Origin).norm ** 2 / self.W0 ** 2) * np.exp(-2 * np.array(np.arccos(np.dot(Directions, mgeo.Vector([1, 0, 0])))) ** 2 / self.Divergence ** 2)
202
203class UniformPowerDistribution(PowerDistribution):
204    """
205    Uniform power distribution.
206    """
207    def __init__(self, Power):
208        self.Power = Power
209
210    def __call__(self, Origins, Directions):
211        """
212        Return the power of the rays coming 
213        from the origin points Origins to the directions Directions.
214        """
215        return self.Power * np.ones(len(Origins))
216
217# %% Specific ray origins distributions
218class PointRayOriginsDistribution(RayOriginsDistribution):
219    """
220    Point ray origins distribution.
221    """
222    def __init__(self, Origin):
223        self.Origin = Origin
224
225    def __call__(self, N):
226        """
227        Return the origins of N rays.
228        """
229        return mgeo.PointArray([self.Origin for i in range(N)])
230    
231class DiskRayOriginsDistribution(RayOriginsDistribution):
232    """
233    Disk ray origins distribution. Uses the Vogel spiral to initialize the rays.
234    """
235    def __init__(self, Origin, Radius, Normal = mgeo.Vector([0, 0, 1])):
236        self.Origin = Origin
237        self.Radius = Radius
238        self.Normal = Normal
239
240    def __call__(self, N):
241        """
242        Return the origins of N rays.
243        """
244        MatrixXY = mgeo.SpiralVogel(N, self.Radius)
245        q = mgeo.QRotationVector2Vector(mgeo.Vector([0, 0, 1]), self.Normal)
246        return mgeo.PointArray([self.Origin + mgeo.Vector([MatrixXY[i, 0], MatrixXY[i, 1], 0]) for i in range(N)]).rotate(q)
247    
248# %% Specific ray directions distributions
249class UniformRayDirectionsDistribution(RayDirectionsDistribution):
250    """
251    Uniform ray directions distribution.
252    """
253    def __init__(self, Direction):
254        self.Direction = Direction
255
256    def __call__(self, N):
257        """
258        Return the directions of N rays.
259        """
260        return mgeo.VectorArray([self.Direction for i in range(N)])
261
262class ConeRayDirectionsDistribution(RayDirectionsDistribution):
263    """
264    Cone ray directions distribution. Uses the Vogel spiral to initialize the rays.
265    """
266    def __init__(self, Direction, Angle):
267        self.Direction = Direction
268        self.Angle = Angle
269
270    def __call__(self, N):
271        """
272        Return the directions of N rays.
273        """
274        Height = 1
275        Radius = Height * np.tan(self.Angle)
276        MatrixXY = mgeo.SpiralVogel(N, Radius)
277        q = mgeo.QRotationVector2Vector(mgeo.Vector([0, 0, 1]), self.Direction)
278        return mgeo.VectorArray([[MatrixXY[i, 0], MatrixXY[i, 1], Height] for i in range(N)]).rotate(q).normalized()
279
280
281# %% Specific spectra
282class SingleWavelengthSpectrum(Spectrum):
283    """
284    Single wavelength spectrum.
285    """
286    def __init__(self, Wavelength):
287        self.Wavelength = Wavelength
288
289    def __call__(self, N):
290        """
291        Return the wavelengths of N rays.
292        """
293        return np.ones(N) * self.Wavelength
294
295class UniformSpectrum(Spectrum):
296    """
297    Uniform spectrum.
298    Can be specified as any combination of min, max, central or width in either eV or nm.
299    """
300    def __init__(self, eVMax = None, eVMin = None, eVCentral = None, 
301                 lambdaMax = None, lambdaMin = None, lambdaCentral = None, 
302                 eVWidth = None, lambdaWidth = None):
303        # Using the DepSolver, we calculate the minimum and maximum wavelengths
304        values, steps = UniformSpectraCalculator().calculate_values(
305            lambda_min = lambdaMin, 
306            lambda_max = lambdaMax, 
307            lambda_center = lambdaCentral, 
308            lambda_width = lambdaWidth,
309            eV_min = eVMin,
310            eV_max = eVMax,
311            eV_center = eVCentral,
312            eV_width = eVWidth
313        )
314        self.lambdaMin = values['lambda_min']
315        self.lambdaMax = values['lambda_max']
316    def __call__(self, N):
317        """
318        Return the wavelengths of N rays.
319        """
320        return np.linspace(self.lambdaMin, self.lambdaMax, N)
321
322
323# %% Simple sources
324class SimpleSource(Source):
325    """
326    A simple monochromatic source defined by 4 parameters:
327    - Wavelength (in nm)
328    - Power distribution
329    - Ray origins distribution
330    - Ray directions distribution
331    """
332
333    def __init__(self, Wavelength, PowerDistribution, RayOriginsDistribution, RayDirectionsDistribution):
334        self.Wavelength = Wavelength
335        self.PowerDistribution = PowerDistribution
336        self.RayOriginsDistribution = RayOriginsDistribution
337        self.RayDirectionsDistribution = RayDirectionsDistribution
338
339    def __call__(self, N):
340        """
341        Return a list of N rays from the simple source.
342        """
343        Origins = self.RayOriginsDistribution(N)
344        rng = np.random.default_rng()
345        rng.shuffle(Origins)
346        Directions = self.RayDirectionsDistribution(N)
347        Powers = self.PowerDistribution(Origins, Directions)
348        
349        RayList = []
350        for i in range(N):
351            RayList.append(mray.Ray(Origins[i], Directions[i], wavelength=self.Wavelength, number=i, intensity=Powers[i]))
352        return mray.RayList.from_list(RayList)
353
354
355class ListSource(Source):
356    """
357    A source containing just a list of rays that can be prepared manually.
358    """
359    def __init__(self, Rays):
360        self.Rays = Rays
361
362    def __call__(self, N):
363        """
364        Return the list of rays.
365        """
366        if N < len(self.Rays):
367            return self.Rays[:N]
368        elif N>len(self.Rays):
369            logger.warning("Requested number of rays is greater than the number of rays in the source. Returning the whole source.")
370            return self.Rays    
371        return mray.RayList.from_list(self.Rays)
logger = <Logger ARTcore.ModuleSource (WARNING)>
class Source(abc.ABC):
34class Source(ABC):
35    """
36    Abstract base class for sources.
37    Fundamentally a source just has to be able to return a list of rays.
38    To do so, we make it callable.
39    """
40    @abstractmethod
41    def __call__(self,N):
42        pass

Abstract base class for sources. Fundamentally a source just has to be able to return a list of rays. To do so, we make it callable.

class PowerDistribution(abc.ABC):
44class PowerDistribution(ABC):
45    """
46    Abstract base class for angular power distributions.
47    """
48    @abstractmethod
49    def __call__(self, Origins, Directions):
50        """
51        Return the power of the rays coming 
52        from the origin points Origins to the directions Directions.
53        """
54        pass

Abstract base class for angular power distributions.

class RayOriginsDistribution(abc.ABC):
55class RayOriginsDistribution(ABC):
56    """
57    Abstract base class for ray origins distributions.
58    """
59    @abstractmethod
60    def __call__(self, N):
61        """
62        Return the origins of N rays.
63        """
64        pass

Abstract base class for ray origins distributions.

class RayDirectionsDistribution(abc.ABC):
66class RayDirectionsDistribution(ABC):
67    """
68    Abstract base class for ray directions distributions.
69    """
70    @abstractmethod
71    def __call__(self, N):
72        """
73        Return the directions of N rays.
74        """
75        pass

Abstract base class for ray directions distributions.

class Spectrum(abc.ABC):
77class Spectrum(ABC):
78    """
79    Abstract base class for spectra.
80    """
81    @abstractmethod
82    def __call__(self, N):
83        """
84        Return the wavelengths of N rays.
85        """
86        pass

Abstract base class for spectra.

class SpatialGaussianPowerDistribution(PowerDistribution):
 89class SpatialGaussianPowerDistribution(PowerDistribution):
 90    """
 91    Spatial Gaussian power distribution, depending only on ray origin points, and not on directions. 
 92    
 93    Attributes
 94    ----------
 95        Power : float
 96            Peak power of the distribution in arbitrary units (user can keep track of their own units.)
 97
 98        W0 : float
 99            1/e^2 beam waist in mm     
100    """
101    def __init__(self, Power, W0):
102        self.Power = Power
103        self.W0 = W0
104
105    def __call__(self, Origins, Directions):
106        """
107        Return the power of the rays coming 
108        from the origin points Origins to the directions Directions.
109        
110        Parameters
111        ----------
112            Origins : mgeo.PointArray 
113               PointArray as defined in ModuleGeometry, with points of origin of the rays.
114
115            Directions : mgeo.VectorArray
116                VectorArray as defined in ModuleGeometry, with ray vectors.
117
118        Returns
119        -------
120            Powers: numpy.array
121                Array of powers for each ray.
122        
123        """
124        return self.Power * np.exp(-2 * np.linalg.norm(Origins, axis=1) ** 2 / self.W0 ** 2)

Spatial Gaussian power distribution, depending only on ray origin points, and not on directions.

Attributes

Power : float
    Peak power of the distribution in arbitrary units (user can keep track of their own units.)

W0 : float
    1/e^2 beam waist in mm
SpatialGaussianPowerDistribution(Power, W0)
101    def __init__(self, Power, W0):
102        self.Power = Power
103        self.W0 = W0
Power
W0
class AngularGaussianPowerDistribution(PowerDistribution):
126class AngularGaussianPowerDistribution(PowerDistribution):
127    """
128    Angular Gaussian power distribution, depending only on ray directions, but not origin points. 
129    
130    Attributes
131    ----------
132        Power : float
133            Peak power of the distribution in arbitrary units (user can keep track of their own units.)
134
135        Divergence : float
136            1/e^2 divergence half-angle in radians.
137    """
138    def __init__(self, Power, Divergence):
139        self.Power = Power
140        self.Divergence = Divergence
141
142    def __call__(self, Origins, Directions):
143        """
144        Return the power of the rays coming 
145        from the origin points Origins to the directions Directions.
146        
147        Parameters
148        ----------
149            Origins : mgeo.PointArray 
150               PointArray as defined in ModuleGeometry, with points of origin of the rays.
151
152            Directions : mgeo.VectorArray
153                VectorArray as defined in ModuleGeometry, with ray vectors.
154
155        Returns
156        -------
157            Powers: numpy.array
158                Array of powers for each ray.
159        
160        """
161        return self.Power * np.exp(-2 * np.arccos(np.dot(Directions, [0, 0, 1])) ** 2 / self.Divergence ** 2)

Angular Gaussian power distribution, depending only on ray directions, but not origin points.

Attributes

Power : float
    Peak power of the distribution in arbitrary units (user can keep track of their own units.)

Divergence : float
    1/e^2 divergence half-angle in radians.
AngularGaussianPowerDistribution(Power, Divergence)
138    def __init__(self, Power, Divergence):
139        self.Power = Power
140        self.Divergence = Divergence
Power
Divergence
class GaussianPowerDistribution(PowerDistribution):
163class GaussianPowerDistribution(PowerDistribution):
164    """
165    Gaussian power distribution, depending on ray origin points and directions.
166    
167    Attributes
168    ----------
169        Power : float
170            Peak power of the distribution in arbitrary units (user can keep track of their own units.)
171
172        W0 : float
173            1/e^2 beam waist in mm            
174
175        Divergence : float
176            1/e^2 divergence half-angle in radians.
177    """
178    def __init__(self, Power, W0, Divergence):
179        self.Power = Power
180        self.W0 = W0
181        self.Divergence = Divergence
182
183    def __call__(self, Origins, Directions):
184        """
185        Return the power of the rays coming 
186        from the origin points Origins to the directions Directions.
187        
188        Parameters
189        ----------
190            Origins : mgeo.PointArray 
191               PointArray as defined in ModuleGeometry, with points of origin of the rays.
192
193            Directions : mgeo.VectorArray
194                VectorArray as defined in ModuleGeometry, with ray vectors.
195
196        Returns
197        -------
198            Powers: numpy.array
199                Array of powers for each ray.
200        
201        """
202        return self.Power * np.exp(-2 * (Origins-mgeo.Origin).norm ** 2 / self.W0 ** 2) * np.exp(-2 * np.array(np.arccos(np.dot(Directions, mgeo.Vector([1, 0, 0])))) ** 2 / self.Divergence ** 2)

Gaussian power distribution, depending on ray origin points and directions.

Attributes

Power : float
    Peak power of the distribution in arbitrary units (user can keep track of their own units.)

W0 : float
    1/e^2 beam waist in mm            

Divergence : float
    1/e^2 divergence half-angle in radians.
GaussianPowerDistribution(Power, W0, Divergence)
178    def __init__(self, Power, W0, Divergence):
179        self.Power = Power
180        self.W0 = W0
181        self.Divergence = Divergence
Power
W0
Divergence
class UniformPowerDistribution(PowerDistribution):
204class UniformPowerDistribution(PowerDistribution):
205    """
206    Uniform power distribution.
207    """
208    def __init__(self, Power):
209        self.Power = Power
210
211    def __call__(self, Origins, Directions):
212        """
213        Return the power of the rays coming 
214        from the origin points Origins to the directions Directions.
215        """
216        return self.Power * np.ones(len(Origins))

Uniform power distribution.

UniformPowerDistribution(Power)
208    def __init__(self, Power):
209        self.Power = Power
Power
class PointRayOriginsDistribution(RayOriginsDistribution):
219class PointRayOriginsDistribution(RayOriginsDistribution):
220    """
221    Point ray origins distribution.
222    """
223    def __init__(self, Origin):
224        self.Origin = Origin
225
226    def __call__(self, N):
227        """
228        Return the origins of N rays.
229        """
230        return mgeo.PointArray([self.Origin for i in range(N)])

Point ray origins distribution.

PointRayOriginsDistribution(Origin)
223    def __init__(self, Origin):
224        self.Origin = Origin
Origin
class DiskRayOriginsDistribution(RayOriginsDistribution):
232class DiskRayOriginsDistribution(RayOriginsDistribution):
233    """
234    Disk ray origins distribution. Uses the Vogel spiral to initialize the rays.
235    """
236    def __init__(self, Origin, Radius, Normal = mgeo.Vector([0, 0, 1])):
237        self.Origin = Origin
238        self.Radius = Radius
239        self.Normal = Normal
240
241    def __call__(self, N):
242        """
243        Return the origins of N rays.
244        """
245        MatrixXY = mgeo.SpiralVogel(N, self.Radius)
246        q = mgeo.QRotationVector2Vector(mgeo.Vector([0, 0, 1]), self.Normal)
247        return mgeo.PointArray([self.Origin + mgeo.Vector([MatrixXY[i, 0], MatrixXY[i, 1], 0]) for i in range(N)]).rotate(q)

Disk ray origins distribution. Uses the Vogel spiral to initialize the rays.

DiskRayOriginsDistribution(Origin, Radius, Normal=Vector([0, 0, 1]))
236    def __init__(self, Origin, Radius, Normal = mgeo.Vector([0, 0, 1])):
237        self.Origin = Origin
238        self.Radius = Radius
239        self.Normal = Normal
Origin
Radius
Normal
class UniformRayDirectionsDistribution(RayDirectionsDistribution):
250class UniformRayDirectionsDistribution(RayDirectionsDistribution):
251    """
252    Uniform ray directions distribution.
253    """
254    def __init__(self, Direction):
255        self.Direction = Direction
256
257    def __call__(self, N):
258        """
259        Return the directions of N rays.
260        """
261        return mgeo.VectorArray([self.Direction for i in range(N)])

Uniform ray directions distribution.

UniformRayDirectionsDistribution(Direction)
254    def __init__(self, Direction):
255        self.Direction = Direction
Direction
class ConeRayDirectionsDistribution(RayDirectionsDistribution):
263class ConeRayDirectionsDistribution(RayDirectionsDistribution):
264    """
265    Cone ray directions distribution. Uses the Vogel spiral to initialize the rays.
266    """
267    def __init__(self, Direction, Angle):
268        self.Direction = Direction
269        self.Angle = Angle
270
271    def __call__(self, N):
272        """
273        Return the directions of N rays.
274        """
275        Height = 1
276        Radius = Height * np.tan(self.Angle)
277        MatrixXY = mgeo.SpiralVogel(N, Radius)
278        q = mgeo.QRotationVector2Vector(mgeo.Vector([0, 0, 1]), self.Direction)
279        return mgeo.VectorArray([[MatrixXY[i, 0], MatrixXY[i, 1], Height] for i in range(N)]).rotate(q).normalized()

Cone ray directions distribution. Uses the Vogel spiral to initialize the rays.

ConeRayDirectionsDistribution(Direction, Angle)
267    def __init__(self, Direction, Angle):
268        self.Direction = Direction
269        self.Angle = Angle
Direction
Angle
class SingleWavelengthSpectrum(Spectrum):
283class SingleWavelengthSpectrum(Spectrum):
284    """
285    Single wavelength spectrum.
286    """
287    def __init__(self, Wavelength):
288        self.Wavelength = Wavelength
289
290    def __call__(self, N):
291        """
292        Return the wavelengths of N rays.
293        """
294        return np.ones(N) * self.Wavelength

Single wavelength spectrum.

SingleWavelengthSpectrum(Wavelength)
287    def __init__(self, Wavelength):
288        self.Wavelength = Wavelength
Wavelength
class UniformSpectrum(Spectrum):
296class UniformSpectrum(Spectrum):
297    """
298    Uniform spectrum.
299    Can be specified as any combination of min, max, central or width in either eV or nm.
300    """
301    def __init__(self, eVMax = None, eVMin = None, eVCentral = None, 
302                 lambdaMax = None, lambdaMin = None, lambdaCentral = None, 
303                 eVWidth = None, lambdaWidth = None):
304        # Using the DepSolver, we calculate the minimum and maximum wavelengths
305        values, steps = UniformSpectraCalculator().calculate_values(
306            lambda_min = lambdaMin, 
307            lambda_max = lambdaMax, 
308            lambda_center = lambdaCentral, 
309            lambda_width = lambdaWidth,
310            eV_min = eVMin,
311            eV_max = eVMax,
312            eV_center = eVCentral,
313            eV_width = eVWidth
314        )
315        self.lambdaMin = values['lambda_min']
316        self.lambdaMax = values['lambda_max']
317    def __call__(self, N):
318        """
319        Return the wavelengths of N rays.
320        """
321        return np.linspace(self.lambdaMin, self.lambdaMax, N)

Uniform spectrum. Can be specified as any combination of min, max, central or width in either eV or nm.

UniformSpectrum( eVMax=None, eVMin=None, eVCentral=None, lambdaMax=None, lambdaMin=None, lambdaCentral=None, eVWidth=None, lambdaWidth=None)
301    def __init__(self, eVMax = None, eVMin = None, eVCentral = None, 
302                 lambdaMax = None, lambdaMin = None, lambdaCentral = None, 
303                 eVWidth = None, lambdaWidth = None):
304        # Using the DepSolver, we calculate the minimum and maximum wavelengths
305        values, steps = UniformSpectraCalculator().calculate_values(
306            lambda_min = lambdaMin, 
307            lambda_max = lambdaMax, 
308            lambda_center = lambdaCentral, 
309            lambda_width = lambdaWidth,
310            eV_min = eVMin,
311            eV_max = eVMax,
312            eV_center = eVCentral,
313            eV_width = eVWidth
314        )
315        self.lambdaMin = values['lambda_min']
316        self.lambdaMax = values['lambda_max']
lambdaMin
lambdaMax
class SimpleSource(Source):
325class SimpleSource(Source):
326    """
327    A simple monochromatic source defined by 4 parameters:
328    - Wavelength (in nm)
329    - Power distribution
330    - Ray origins distribution
331    - Ray directions distribution
332    """
333
334    def __init__(self, Wavelength, PowerDistribution, RayOriginsDistribution, RayDirectionsDistribution):
335        self.Wavelength = Wavelength
336        self.PowerDistribution = PowerDistribution
337        self.RayOriginsDistribution = RayOriginsDistribution
338        self.RayDirectionsDistribution = RayDirectionsDistribution
339
340    def __call__(self, N):
341        """
342        Return a list of N rays from the simple source.
343        """
344        Origins = self.RayOriginsDistribution(N)
345        rng = np.random.default_rng()
346        rng.shuffle(Origins)
347        Directions = self.RayDirectionsDistribution(N)
348        Powers = self.PowerDistribution(Origins, Directions)
349        
350        RayList = []
351        for i in range(N):
352            RayList.append(mray.Ray(Origins[i], Directions[i], wavelength=self.Wavelength, number=i, intensity=Powers[i]))
353        return mray.RayList.from_list(RayList)

A simple monochromatic source defined by 4 parameters:

  • Wavelength (in nm)
  • Power distribution
  • Ray origins distribution
  • Ray directions distribution
SimpleSource( Wavelength, PowerDistribution, RayOriginsDistribution, RayDirectionsDistribution)
334    def __init__(self, Wavelength, PowerDistribution, RayOriginsDistribution, RayDirectionsDistribution):
335        self.Wavelength = Wavelength
336        self.PowerDistribution = PowerDistribution
337        self.RayOriginsDistribution = RayOriginsDistribution
338        self.RayDirectionsDistribution = RayDirectionsDistribution
Wavelength
PowerDistribution
RayOriginsDistribution
RayDirectionsDistribution
class ListSource(Source):
356class ListSource(Source):
357    """
358    A source containing just a list of rays that can be prepared manually.
359    """
360    def __init__(self, Rays):
361        self.Rays = Rays
362
363    def __call__(self, N):
364        """
365        Return the list of rays.
366        """
367        if N < len(self.Rays):
368            return self.Rays[:N]
369        elif N>len(self.Rays):
370            logger.warning("Requested number of rays is greater than the number of rays in the source. Returning the whole source.")
371            return self.Rays    
372        return mray.RayList.from_list(self.Rays)

A source containing just a list of rays that can be prepared manually.

ListSource(Rays)
360    def __init__(self, Rays):
361        self.Rays = Rays
Rays