Coverage for colorimetry/generation.py: 53%
79 statements
« prev ^ index » next coverage.py v7.11.0, created at 2025-11-16 22:49 +1300
« prev ^ index » next coverage.py v7.11.0, created at 2025-11-16 22:49 +1300
1"""
2Spectral Generation
3===================
5Define objects for generating spectral distributions and multi-spectral
6distributions with the specified characteristics.
8- :func:`colour.sd_constant`
9- :func:`colour.sd_zeros`
10- :func:`colour.sd_ones`
11- :func:`colour.msds_constant`
12- :func:`colour.msds_zeros`
13- :func:`colour.msds_ones`
14- :func:`colour.colorimetry.sd_gaussian_normal`
15- :func:`colour.colorimetry.sd_gaussian_fwhm`
16- :attr:`colour.SD_GAUSSIAN_METHODS`
17- :func:`colour.sd_gaussian`
18- :func:`colour.colorimetry.sd_single_led_Ohno2005`
19- :attr:`colour.SD_SINGLE_LED_METHODS`
20- :func:`colour.sd_single_led`
21- :func:`colour.colorimetry.sd_multi_leds_Ohno2005`
22- :attr:`colour.SD_MULTI_LEDS_METHODS`
23- :func:`colour.sd_multi_leds`
25References
26----------
27- :cite:`Ohno2005` : Ohno, Yoshi. (2005). Spectral design considerations for
28 white LED color rendering. Optical Engineering, 44(11), 111302.
29 doi:10.1117/1.2130694
30- :cite:`Ohno2008a` : Ohno, Yoshiro, & Davis, W. (2008). NIST CQS simulation
31 (Version 7.4) [Computer software].
32 https://drive.google.com/file/d/1PsuU6QjUJjCX6tQyCud6ul2Tbs8rYWW9/view?\
33usp=sharing
34"""
36from __future__ import annotations
38import typing
40import numpy as np
42from colour.algebra.interpolation import LinearInterpolator
43from colour.colorimetry import (
44 SPECTRAL_SHAPE_DEFAULT,
45 MultiSpectralDistributions,
46 SpectralDistribution,
47 SpectralShape,
48)
50if typing.TYPE_CHECKING:
51 from colour.hints import (
52 Any,
53 ArrayLike,
54 Literal,
55 NDArrayFloat,
56 Sequence,
57 )
59from colour.utilities import (
60 CanonicalMapping,
61 as_float_array,
62 full,
63 ones,
64 validate_method,
65)
67__author__ = "Colour Developers"
68__copyright__ = "Copyright 2013 Colour Developers"
69__license__ = "BSD-3-Clause - https://opensource.org/licenses/BSD-3-Clause"
70__maintainer__ = "Colour Developers"
71__email__ = "colour-developers@colour-science.org"
72__status__ = "Production"
74__all__ = [
75 "sd_constant",
76 "sd_zeros",
77 "sd_ones",
78 "msds_constant",
79 "msds_zeros",
80 "msds_ones",
81 "sd_gaussian_normal",
82 "sd_gaussian_fwhm",
83 "SD_GAUSSIAN_METHODS",
84 "sd_gaussian",
85 "sd_single_led_Ohno2005",
86 "SD_SINGLE_LED_METHODS",
87 "sd_single_led",
88 "sd_multi_leds_Ohno2005",
89 "SD_MULTI_LEDS_METHODS",
90 "sd_multi_leds",
91]
94def sd_constant(
95 k: float, shape: SpectralShape = SPECTRAL_SHAPE_DEFAULT, **kwargs: Any
96) -> SpectralDistribution:
97 """
98 Generate a spectral distribution of the specified spectral shape filled with
99 constant :math:`k` values.
101 Parameters
102 ----------
103 k
104 Constant :math:`k` to fill the spectral distribution with.
105 shape
106 Spectral shape used to create the spectral distribution.
108 Other Parameters
109 ----------------
110 kwargs
111 {:class:`colour.SpectralDistribution`},
112 See the documentation of the previously listed class.
114 Returns
115 -------
116 :class:`colour.SpectralDistribution`
117 Constant :math:`k` filled spectral distribution.
119 Notes
120 -----
121 - By default, the spectral distribution will use the shape specified by
122 :attr:`colour.SPECTRAL_SHAPE_DEFAULT` attribute.
123 - The interpolator is set to :class:`colour.LinearInterpolator` class.
125 Examples
126 --------
127 >>> sd = sd_constant(100)
128 >>> sd.shape
129 SpectralShape(360.0, 780.0, 1.0)
130 >>> sd[400]
131 100.0
132 """
134 settings = {"name": f"{k} Constant", "interpolator": LinearInterpolator}
135 settings.update(kwargs)
137 values = full(len(shape.wavelengths), k)
139 return SpectralDistribution(values, shape.wavelengths, **settings)
142def sd_zeros(
143 shape: SpectralShape = SPECTRAL_SHAPE_DEFAULT, **kwargs: Any
144) -> SpectralDistribution:
145 """
146 Generate a spectral distribution of the specified spectral shape filled with
147 zeros.
149 Parameters
150 ----------
151 shape
152 Spectral shape used to create the spectral distribution.
154 Other Parameters
155 ----------------
156 kwargs
157 {:func:`colour.sd_constant`},
158 See the documentation of the previously listed definition.
160 Returns
161 -------
162 :class:`colour.SpectralDistribution`
163 Zeros-filled spectral distribution.
165 Notes
166 -----
167 - By default, the spectral distribution will use the shape specified by
168 :attr:`colour.SPECTRAL_SHAPE_DEFAULT` attribute.
169 - The interpolator is set to :class:`colour.LinearInterpolator` class.
171 Examples
172 --------
173 >>> sd = sd_zeros()
174 >>> sd.shape
175 SpectralShape(360.0, 780.0, 1.0)
176 >>> sd[400]
177 0.0
178 """
180 return sd_constant(0, shape, **kwargs)
183def sd_ones(
184 shape: SpectralShape = SPECTRAL_SHAPE_DEFAULT, **kwargs: Any
185) -> SpectralDistribution:
186 """
187 Generate a spectral distribution of the specified spectral shape filled
188 with ones.
190 Parameters
191 ----------
192 shape
193 Spectral shape used to create the spectral distribution.
195 Other Parameters
196 ----------------
197 kwargs
198 {:func:`colour.sd_constant`},
199 See the documentation of the previously listed definition.
201 Returns
202 -------
203 :class:`colour.SpectralDistribution`
204 Ones-filled spectral distribution.
206 Notes
207 -----
208 - By default, the spectral distribution will use the shape specified by
209 :attr:`colour.SPECTRAL_SHAPE_DEFAULT` attribute.
210 - The interpolator is set to :class:`colour.LinearInterpolator` class.
212 Examples
213 --------
214 >>> sd = sd_ones()
215 >>> sd.shape
216 SpectralShape(360.0, 780.0, 1.0)
217 >>> sd[400]
218 1.0
219 """
221 return sd_constant(1, shape, **kwargs)
224def msds_constant(
225 k: float,
226 labels: Sequence,
227 shape: SpectralShape = SPECTRAL_SHAPE_DEFAULT,
228 **kwargs: Any,
229) -> MultiSpectralDistributions:
230 """
231 Generate multi-spectral distributions with the specified labels and spectral
232 shape filled with constant :math:`k` values.
234 Parameters
235 ----------
236 k
237 Constant :math:`k` to fill the multi-spectral distributions with.
238 labels
239 Names to use for the :class:`colour.SpectralDistribution` class
240 instances.
241 shape
242 Spectral shape used to create the multi-spectral distributions.
244 Other Parameters
245 ----------------
246 kwargs
247 {:class:`colour.MultiSpectralDistributions`},
248 See the documentation of the previously listed class.
250 Returns
251 -------
252 :class:`colour.MultiSpectralDistributions`
253 Constant :math:`k` filled multi-spectral distributions.
255 Notes
256 -----
257 - By default, the multi-spectral distributions will use the shape
258 specified by :attr:`colour.SPECTRAL_SHAPE_DEFAULT` attribute.
259 - The interpolator is set to :class:`colour.LinearInterpolator` class.
261 Examples
262 --------
263 >>> msds = msds_constant(100, labels=["a", "b", "c"])
264 >>> msds.shape
265 SpectralShape(360.0, 780.0, 1.0)
266 >>> msds[400]
267 array([ 100., 100., 100.])
268 >>> msds.labels # doctest: +SKIP
269 ['a', 'b', 'c']
270 """
272 settings = {"name": f"{k} Constant", "interpolator": LinearInterpolator}
273 settings.update(kwargs)
275 wavelengths = shape.wavelengths
276 values = full((len(wavelengths), len(labels)), k)
278 return MultiSpectralDistributions(values, wavelengths, labels=labels, **settings)
281def msds_zeros(
282 labels: Sequence,
283 shape: SpectralShape = SPECTRAL_SHAPE_DEFAULT,
284 **kwargs: Any,
285) -> MultiSpectralDistributions:
286 """
287 Generate multi-spectral distributions with the specified labels and spectral
288 shape filled with zeros.
290 Parameters
291 ----------
292 labels
293 Names to use for the :class:`colour.SpectralDistribution` class
294 instances.
295 shape
296 Spectral shape used to create the multi-spectral distributions.
298 Other Parameters
299 ----------------
300 kwargs
301 {:func:`colour.msds_constant`},
302 See the documentation of the previously listed definition.
304 Returns
305 -------
306 :class:`colour.MultiSpectralDistributions`
307 Zero-filled multi-spectral distributions.
309 Notes
310 -----
311 - By default, the multi-spectral distributions will use the shape
312 specified by :attr:`colour.SPECTRAL_SHAPE_DEFAULT` attribute.
313 - The interpolator is set to :class:`colour.LinearInterpolator` class.
315 Examples
316 --------
317 >>> msds = msds_zeros(labels=["a", "b", "c"])
318 >>> msds.shape
319 SpectralShape(360.0, 780.0, 1.0)
320 >>> msds[400]
321 array([ 0., 0., 0.])
322 >>> msds.labels # doctest: +SKIP
323 ['a', 'b', 'c']
324 """
326 return msds_constant(0, labels, shape, **kwargs)
329def msds_ones(
330 labels: Sequence,
331 shape: SpectralShape = SPECTRAL_SHAPE_DEFAULT,
332 **kwargs: Any,
333) -> MultiSpectralDistributions:
334 """
335 Generate multi-spectral distributions with the specified labels and
336 spectral shape filled with ones.
338 Parameters
339 ----------
340 labels
341 Names to use for the :class:`colour.SpectralDistribution` class
342 instances.
343 shape
344 Spectral shape used to create the multi-spectral distributions.
346 Other Parameters
347 ----------------
348 kwargs
349 {:func:`colour.msds_constant`},
350 See the documentation of the previously listed definition.
352 Returns
353 -------
354 :class:`colour.MultiSpectralDistributions`
355 Ones-filled multi-spectral distributions.
357 Notes
358 -----
359 - By default, the multi-spectral distributions will use the shape
360 specified by :attr:`colour.SPECTRAL_SHAPE_DEFAULT` attribute.
361 - The interpolator is set to :class:`colour.LinearInterpolator`
362 class.
364 Examples
365 --------
366 >>> msds = msds_ones(labels=["a", "b", "c"])
367 >>> msds.shape
368 SpectralShape(360.0, 780.0, 1.0)
369 >>> msds[400]
370 array([ 1., 1., 1.])
371 >>> msds.labels # doctest: +SKIP
372 ['a', 'b', 'c']
373 """
375 return msds_constant(1, labels, shape, **kwargs)
378def sd_gaussian_normal(
379 mu: float,
380 sigma: float,
381 shape: SpectralShape = SPECTRAL_SHAPE_DEFAULT,
382 **kwargs: Any,
383) -> SpectralDistribution:
384 r"""
385 Generate a Gaussian spectral distribution of the specified spectral shape at
386 specified mean wavelength :math:`\mu` and standard deviation
387 :math:`\sigma`.
389 Parameters
390 ----------
391 mu
392 Mean wavelength :math:`\mu` at which the Gaussian spectral
393 distribution will peak.
394 sigma
395 Standard deviation :math:`\sigma` of the Gaussian spectral
396 distribution.
397 shape
398 Spectral shape used to create the spectral distribution.
400 Other Parameters
401 ----------------
402 kwargs
403 {:class:`colour.SpectralDistribution`},
404 See the documentation of the previously listed class.
406 Returns
407 -------
408 :class:`colour.SpectralDistribution`
409 Gaussian spectral distribution.
411 Notes
412 -----
413 - By default, the spectral distribution will use the shape specified by
414 :attr:`colour.SPECTRAL_SHAPE_DEFAULT` attribute.
416 Examples
417 --------
418 >>> sd = sd_gaussian_normal(555, 25)
419 >>> sd.shape
420 SpectralShape(360.0, 780.0, 1.0)
421 >>> sd[555] # doctest: +SKIP
422 1.0
423 >>> sd[530] # doctest: +ELLIPSIS
424 0.6065306...
425 """
427 settings = {"name": f"{mu}nm - {sigma} Sigma - Gaussian"}
428 settings.update(kwargs)
430 values = np.exp(-((shape.wavelengths - mu) ** 2) / (2 * sigma**2))
432 return SpectralDistribution(values, shape.wavelengths, **settings)
435def sd_gaussian_fwhm(
436 peak_wavelength: float,
437 fwhm: float,
438 shape: SpectralShape = SPECTRAL_SHAPE_DEFAULT,
439 **kwargs: Any,
440) -> SpectralDistribution:
441 """
442 Generate a Gaussian spectral distribution of the specified spectral shape at
443 specified peak wavelength and full width at half maximum (FWHM).
445 Parameters
446 ----------
447 peak_wavelength
448 Wavelength at which the Gaussian spectral distribution peaks.
449 fwhm
450 Full width at half maximum, i.e., width of the Gaussian spectral
451 distribution measured between those points on the *y* axis which are
452 half the maximum amplitude.
453 shape
454 Spectral shape used to create the spectral distribution.
456 Other Parameters
457 ----------------
458 kwargs
459 {:class:`colour.SpectralDistribution`},
460 See the documentation of the previously listed class.
462 Returns
463 -------
464 :class:`colour.SpectralDistribution`
465 Gaussian spectral distribution.
467 Notes
468 -----
469 - By default, the spectral distribution will use the shape specified by
470 :attr:`colour.SPECTRAL_SHAPE_DEFAULT` attribute.
472 Examples
473 --------
474 >>> sd = sd_gaussian_fwhm(555, 25)
475 >>> sd.shape
476 SpectralShape(360.0, 780.0, 1.0)
477 >>> sd[555] # doctest: +SKIP
478 1.0
479 >>> sd[530] # doctest: +ELLIPSIS
480 0.062...
481 """
483 settings = {"name": f"{peak_wavelength}nm - {fwhm} FWHM - Gaussian"}
484 settings.update(kwargs)
486 mu, sigma = peak_wavelength, fwhm / (2 * np.sqrt(2 * np.log(2)))
487 values = np.exp(-((shape.wavelengths - mu) ** 2) / (2 * sigma**2))
489 return SpectralDistribution(values, shape.wavelengths, **settings)
492SD_GAUSSIAN_METHODS: CanonicalMapping = CanonicalMapping(
493 {"Normal": sd_gaussian_normal, "FWHM": sd_gaussian_fwhm}
494)
495SD_GAUSSIAN_METHODS.__doc__ = """
496Supported gaussian spectral distribution generation methods.
497"""
500def sd_gaussian(
501 mu_peak_wavelength: float,
502 sigma_fwhm: float,
503 shape: SpectralShape = SPECTRAL_SHAPE_DEFAULT,
504 method: Literal["Normal", "FWHM"] | str = "Normal",
505 **kwargs: Any,
506) -> SpectralDistribution:
507 """
508 Generate a Gaussian spectral distribution with the specified spectral
509 shape using the specified method.
511 Parameters
512 ----------
513 mu_peak_wavelength
514 Mean wavelength :math:`\\mu` at which the Gaussian spectral
515 distribution will peak.
516 sigma_fwhm
517 Standard deviation :math:`\\sigma` of the Gaussian spectral
518 distribution or full width at half maximum (FWHM), i.e., the width
519 of the Gaussian spectral distribution measured between those points
520 on the *y* axis which are half the maximum amplitude.
521 shape
522 Spectral shape used to create the spectral distribution.
523 method
524 Computation method.
526 Other Parameters
527 ----------------
528 kwargs
529 {:func:`colour.colorimetry.sd_gaussian_normal`,
530 :func:`colour.colorimetry.sd_gaussian_fwhm`},
531 See the documentation of the previously listed definitions.
533 Returns
534 -------
535 :class:`colour.SpectralDistribution`
536 Gaussian spectral distribution.
538 Notes
539 -----
540 - By default, the spectral distribution will use the shape specified
541 by :attr:`colour.SPECTRAL_SHAPE_DEFAULT` attribute.
543 Examples
544 --------
545 >>> sd = sd_gaussian(555, 25)
546 >>> sd.shape
547 SpectralShape(360.0, 780.0, 1.0)
548 >>> sd[555] # doctest: +SKIP
549 1.0
550 >>> sd[530] # doctest: +ELLIPSIS
551 0.6065306...
552 >>> sd = sd_gaussian(555, 25, method="FWHM")
553 >>> sd.shape
554 SpectralShape(360.0, 780.0, 1.0)
555 >>> sd[555] # doctest: +SKIP
556 1.0
557 >>> sd[530] # doctest: +ELLIPSIS
558 0.062...
559 """
561 method = validate_method(method, tuple(SD_GAUSSIAN_METHODS))
563 return SD_GAUSSIAN_METHODS[method](mu_peak_wavelength, sigma_fwhm, shape, **kwargs)
566def sd_single_led_Ohno2005(
567 peak_wavelength: float,
568 half_spectral_width: float,
569 shape: SpectralShape = SPECTRAL_SHAPE_DEFAULT,
570 **kwargs: Any,
571) -> SpectralDistribution:
572 """
573 Generate a single *LED* spectral distribution with the specified spectral
574 shape at specified peak wavelength and half spectral width
575 :math:`\\Delta\\lambda_{0.5}` using *Ohno (2005)* method.
577 Parameters
578 ----------
579 peak_wavelength
580 Wavelength at which the single *LED* spectral distribution peaks.
581 half_spectral_width
582 Half spectral width :math:`\\Delta\\lambda_{0.5}`.
583 shape
584 Spectral shape used to create the spectral distribution.
586 Other Parameters
587 ----------------
588 kwargs
589 {:class:`colour.SpectralDistribution`},
590 See the documentation of the previously listed class.
592 Returns
593 -------
594 :class:`colour.SpectralDistribution`
595 Single *LED* spectral distribution.
597 Notes
598 -----
599 - By default, the spectral distribution will use the shape specified
600 by :attr:`colour.SPECTRAL_SHAPE_DEFAULT` attribute.
602 References
603 ----------
604 :cite:`Ohno2005`, :cite:`Ohno2008a`
606 Examples
607 --------
608 >>> sd = sd_single_led_Ohno2005(555, 25)
609 >>> sd.shape
610 SpectralShape(360.0, 780.0, 1.0)
611 >>> sd[555] # doctest: +ELLIPSIS
612 1...
613 """
615 settings = {
616 "name": f"{peak_wavelength}nm - {half_spectral_width} "
617 f"Half Spectral Width LED - Ohno (2005)"
618 }
619 settings.update(kwargs)
621 values = np.exp(
622 -(((shape.wavelengths - peak_wavelength) / half_spectral_width) ** 2)
623 )
624 values = (values + 2 * values**5) / 3
626 return SpectralDistribution(values, shape.wavelengths, **settings)
629SD_SINGLE_LED_METHODS: CanonicalMapping = CanonicalMapping(
630 {
631 "Ohno 2005": sd_single_led_Ohno2005,
632 }
633)
634SD_SINGLE_LED_METHODS.__doc__ = """
635Supported single *LED* spectral distribution computation methods.
636"""
639def sd_single_led(
640 peak_wavelength: float,
641 shape: SpectralShape = SPECTRAL_SHAPE_DEFAULT,
642 method: Literal["Ohno 2005"] | str = "Ohno 2005",
643 **kwargs: Any,
644) -> SpectralDistribution:
645 """
646 Generate a single *LED* spectral distribution with the specified spectral
647 shape at the specified peak wavelength using the specified method.
649 Parameters
650 ----------
651 peak_wavelength
652 Wavelength the single *LED* spectral distribution will peak at.
653 shape
654 Spectral shape used to create the spectral distribution.
655 method
656 Computation method.
658 Other Parameters
659 ----------------
660 kwargs
661 {:func:`colour.colorimetry.sd_single_led_Ohno2005`},
662 See the documentation of the previously listed definition.
664 Returns
665 -------
666 :class:`colour.SpectralDistribution`
667 Single *LED* spectral distribution.
669 Notes
670 -----
671 - By default, the spectral distribution will use the shape specified by
672 :attr:`colour.SPECTRAL_SHAPE_DEFAULT` attribute.
674 References
675 ----------
676 :cite:`Ohno2005`, :cite:`Ohno2008a`
678 Examples
679 --------
680 >>> sd = sd_single_led(555, half_spectral_width=25)
681 >>> sd.shape
682 SpectralShape(360.0, 780.0, 1.0)
683 >>> sd[555] # doctest: +ELLIPSIS
684 1...
685 """
687 method = validate_method(method, tuple(SD_SINGLE_LED_METHODS))
688 kwargs["shape"] = shape
690 return SD_SINGLE_LED_METHODS[method](peak_wavelength, **kwargs)
693def sd_multi_leds_Ohno2005(
694 peak_wavelengths: ArrayLike,
695 half_spectral_widths: ArrayLike,
696 peak_power_ratios: ArrayLike | None = None,
697 shape: SpectralShape = SPECTRAL_SHAPE_DEFAULT,
698 **kwargs: Any,
699) -> SpectralDistribution:
700 """
701 Generate a multi-*LED* spectral distribution with the specified spectral
702 shape at specified peak wavelengths, half spectral widths
703 :math:`\\Delta\\lambda_{0.5}`, and peak power ratios according to the
704 *Ohno (2005)* method.
706 The multi-*LED* spectral distribution is computed by summing multiple
707 single *LED* spectral distributions generated with the
708 :func:`colour.sd_single_led_Ohno2005` function.
710 Parameters
711 ----------
712 peak_wavelengths
713 Wavelengths at which the multi-*LED* spectral distribution will
714 peak, i.e., the peak wavelengths for each constituent single *LED*
715 spectral distribution.
716 half_spectral_widths
717 Half spectral widths :math:`\\Delta\\lambda_{0.5}` for each
718 constituent single *LED* spectral distribution.
719 peak_power_ratios
720 Peak power ratios for each constituent single *LED* spectral
721 distribution. If not specified, defaults to unity for all *LEDs*.
722 shape
723 Spectral shape used to create the spectral distribution.
725 Other Parameters
726 ----------------
727 kwargs
728 {:func:`colour.colorimetry.sd_single_led_Ohno2005`},
729 See the documentation of the previously listed definition.
731 Returns
732 -------
733 :class:`colour.SpectralDistribution`
734 Multi-*LED* spectral distribution.
736 Notes
737 -----
738 - By default, the spectral distribution will use the shape specified
739 by :attr:`colour.SPECTRAL_SHAPE_DEFAULT` attribute.
741 References
742 ----------
743 :cite:`Ohno2005`, :cite:`Ohno2008a`
745 Examples
746 --------
747 >>> sd = sd_multi_leds_Ohno2005(
748 ... np.array([457, 530, 615]),
749 ... np.array([20, 30, 20]),
750 ... np.array([0.731, 1.000, 1.660]),
751 ... )
752 >>> sd.shape
753 SpectralShape(360.0, 780.0, 1.0)
754 >>> sd[500] # doctest: +ELLIPSIS
755 0.1295132...
756 """
758 peak_wavelengths = as_float_array(peak_wavelengths)
759 half_spectral_widths = np.resize(half_spectral_widths, peak_wavelengths.shape)
760 if peak_power_ratios is None:
761 peak_power_ratios = ones(peak_wavelengths.shape)
762 else:
763 peak_power_ratios = np.resize(peak_power_ratios, peak_wavelengths.shape)
765 sd = sd_zeros(shape)
767 for peak_wavelength, half_spectral_width, peak_power_ratio in zip(
768 peak_wavelengths, half_spectral_widths, peak_power_ratios, strict=True
769 ):
770 sd += (
771 sd_single_led_Ohno2005(peak_wavelength, half_spectral_width, **kwargs)
772 * peak_power_ratio
773 )
775 def _format_array(a: NDArrayFloat) -> str:
776 """Format specified array :math:`a`."""
778 return ", ".join([str(e) for e in a])
780 sd.name = (
781 f"{_format_array(peak_wavelengths)}nm - "
782 f"{_format_array(half_spectral_widths)} FWHM - "
783 f"{_format_array(peak_power_ratios)} Peak Power Ratios - "
784 f"LED - Ohno (2005)"
785 )
787 return sd
790SD_MULTI_LEDS_METHODS: CanonicalMapping = CanonicalMapping(
791 {
792 "Ohno 2005": sd_multi_leds_Ohno2005,
793 }
794)
795SD_MULTI_LEDS_METHODS.__doc__ = """
796Supported multi-*LED* spectral distribution computation methods.
797"""
800def sd_multi_leds(
801 peak_wavelengths: ArrayLike,
802 shape: SpectralShape = SPECTRAL_SHAPE_DEFAULT,
803 method: Literal["Ohno 2005"] | str = "Ohno 2005",
804 **kwargs: Any,
805) -> SpectralDistribution:
806 """
807 Generate a multi-*LED* spectral distribution with the specified spectral
808 shape at specified peak wavelengths.
810 Parameters
811 ----------
812 peak_wavelengths
813 Wavelengths at which the multi-*LED* spectral distribution will
814 peak, i.e., the peak wavelengths for each generated single *LED*
815 spectral distribution.
816 shape
817 Spectral shape used to create the spectral distribution.
818 method
819 Computation method.
821 Other Parameters
822 ----------------
823 kwargs
824 {:func:`colour.colorimetry.sd_multi_leds_Ohno2005`},
825 See the documentation of the previously listed definition.
827 Returns
828 -------
829 :class:`colour.SpectralDistribution`
830 Multi-*LED* spectral distribution.
832 Notes
833 -----
834 - By default, the spectral distribution will use the shape specified
835 by :attr:`colour.SPECTRAL_SHAPE_DEFAULT` attribute.
837 References
838 ----------
839 :cite:`Ohno2005`, :cite:`Ohno2008a`
841 Examples
842 --------
843 >>> sd = sd_multi_leds(
844 ... np.array([457, 530, 615]),
845 ... half_spectral_widths=np.array([20, 30, 20]),
846 ... peak_power_ratios=np.array([0.731, 1.000, 1.660]),
847 ... )
848 >>> sd.shape
849 SpectralShape(360.0, 780.0, 1.0)
850 >>> sd[500] # doctest: +ELLIPSIS
851 0.1295132...
852 """
854 method = validate_method(method, tuple(SD_MULTI_LEDS_METHODS))
855 kwargs["shape"] = shape
857 return SD_MULTI_LEDS_METHODS[method](peak_wavelengths, **kwargs)