Beispiel #1
0
    def test_multi_sds_to_XYZ_integration(self):
        """
        Tests :func:`colour.colorimetry.tristimulus.\
multi_sds_to_XYZ_integration`
        definition.
        """

        cmfs = CMFS['CIE 1931 2 Degree Standard Observer']
        np.testing.assert_almost_equal(
            multi_sds_to_XYZ_integration(MSDS, cmfs, ILLUMINANTS_SDS['D65']),
            XYZ_D65_INTEGRATION_MSDS,
            decimal=7)

        np.testing.assert_almost_equal(
            multi_sds_to_XYZ_integration(
                MSDS_ARRAY,
                cmfs,
                ILLUMINANTS_SDS['D65'],
                shape=SpectralShape(400, 700, 60)),
            XYZ_D65_ARRAY_INTEGRATION,
            decimal=7)

        np.testing.assert_almost_equal(
            multi_sds_to_XYZ_integration(
                MSDS_ARRAY,
                cmfs,
                ILLUMINANTS_SDS['D65'],
                1,
                shape=SpectralShape(400, 700, 60)),
            XYZ_D65_ARRAY_K1_INTEGRATION,
            decimal=7)
Beispiel #2
0
    def test_msds_to_XYZ_integration(self):
        """
        Test :func:`colour.colorimetry.tristimulus_values.\
msds_to_XYZ_integration` definition.
        """

        cmfs = MSDS_CMFS["CIE 1931 2 Degree Standard Observer"]
        np.testing.assert_almost_equal(
            msds_to_XYZ_integration(MSDS_TWO, cmfs, SDS_ILLUMINANTS["D65"]),
            TVS_D65_INTEGRATION_MSDS,
            decimal=7,
        )

        np.testing.assert_almost_equal(
            msds_to_XYZ_integration(
                DATA_TWO,
                cmfs,
                SDS_ILLUMINANTS["D65"],
                shape=SpectralShape(400, 700, 60),
            ),
            TVS_D65_ARRAY_INTEGRATION,
            decimal=7,
        )

        np.testing.assert_almost_equal(
            msds_to_XYZ_integration(
                DATA_TWO,
                cmfs,
                SDS_ILLUMINANTS["D65"],
                1,
                shape=SpectralShape(400, 700, 60),
            ),
            TVS_D65_ARRAY_K1_INTEGRATION,
            decimal=7,
        )
Beispiel #3
0
    def test_sd_to_XYZ_ASTME30815_mi_1nm(self):
        """
        Tests :func:`colour.colorimetry.tristimulus.sd_to_XYZ_ASTME30815`
        definition for 1 nm measurement intervals.
        """

        np.testing.assert_almost_equal(
            sd_to_XYZ_ASTME30815(self._sd.copy().align(self._cmfs.shape),
                                 self._cmfs, self._A),
            np.array([14.46372680, 10.85832950, 2.04663200]),
            decimal=7)

        np.testing.assert_almost_equal(
            sd_to_XYZ_ASTME30815(self._sd.copy().align(self._cmfs.shape),
                                 self._cmfs,
                                 self._A,
                                 use_practice_range=False),
            np.array([14.46366018, 10.85827949, 2.04662258]),
            decimal=7)

        np.testing.assert_almost_equal(
            sd_to_XYZ_ASTME30815(
                self._sd.copy().align(SpectralShape(400, 700, 1)), self._cmfs,
                self._A),
            np.array([14.54173397, 10.88628632, 2.04965822]),
            decimal=7)

        np.testing.assert_almost_equal(
            sd_to_XYZ_ASTME30815(self._sd.copy().align(
                SpectralShape(400, 700, 1)),
                                 self._cmfs,
                                 self._A,
                                 use_practice_range=False),
            np.array([14.54203076, 10.88636754, 2.04964877]),
            decimal=7)
Beispiel #4
0
    def test_spectral_to_XYZ_tristimulus_weighting_factors_ASTME30815(self):
        """
        Tests :func:`colour.colorimetry.tristimulus.\
spectral_to_XYZ_tristimulus_weighting_factors_ASTME30815`
        definition.
        """

        cmfs = CMFS.get('CIE 1931 2 Degree Standard Observer')
        np.testing.assert_almost_equal(
            spectral_to_XYZ_tristimulus_weighting_factors_ASTME30815(
                SAMPLE_SPD,
                cmfs,
                ILLUMINANTS_RELATIVE_SPDS.get('A')),
            np.array([14.46366344, 10.85828513, 2.04663792]),
            decimal=7)

        cmfs = CMFS.get('CIE 1964 10 Degree Standard Observer')
        np.testing.assert_almost_equal(
            spectral_to_XYZ_tristimulus_weighting_factors_ASTME30815(
                SAMPLE_SPD,
                cmfs,
                ILLUMINANTS_RELATIVE_SPDS.get('C')),
            np.array([10.77033881, 9.44864632, 6.62758924]),
            decimal=7)

        np.testing.assert_almost_equal(
            spectral_to_XYZ_tristimulus_weighting_factors_ASTME30815(
                SAMPLE_SPD,
                cmfs,
                ILLUMINANTS_RELATIVE_SPDS.get('F2')),
            np.array([11.57837130, 9.98734511, 3.95499522]),
            decimal=7)

        np.testing.assert_almost_equal(
            spectral_to_XYZ_tristimulus_weighting_factors_ASTME30815(
                SAMPLE_SPD.clone().trim_wavelengths(
                    SpectralShape(400, 700, 5)),
                cmfs,
                ILLUMINANTS_RELATIVE_SPDS.get('A')),
            np.array([14.38180830, 10.74512906, 2.01579131]),
            decimal=7)

        np.testing.assert_almost_equal(
            spectral_to_XYZ_tristimulus_weighting_factors_ASTME30815(
                SAMPLE_SPD.clone().interpolate(
                    SpectralShape(400, 700, 10)),
                cmfs,
                ILLUMINANTS_RELATIVE_SPDS.get('A')),
            np.array([14.38284399, 10.74577954, 2.01553721]),
            decimal=7)

        np.testing.assert_almost_equal(
            spectral_to_XYZ_tristimulus_weighting_factors_ASTME30815(
                SAMPLE_SPD.clone().interpolate(
                    SpectralShape(400, 700, 20)),
                cmfs,
                ILLUMINANTS_RELATIVE_SPDS.get('A')),
            np.array([14.38356848, 10.74613294, 2.01526418]),
            decimal=7)
Beispiel #5
0
    def test_sd_to_XYZ_ASTME308_mi_10nm(self):
        """
        Test :func:`colour.colorimetry.tristimulus_values.sd_to_XYZ_ASTME308`
        definition for 10 nm measurement intervals.
        """

        np.testing.assert_almost_equal(
            sd_to_XYZ_ASTME308(
                reshape_sd(self._sd, SpectralShape(360, 830, 10)),
                self._cmfs,
                self._A,
            ),
            np.array([14.47779980, 10.86358645, 2.04751388]),
            decimal=7,
        )

        np.testing.assert_almost_equal(
            sd_to_XYZ_ASTME308(
                reshape_sd(self._sd, SpectralShape(360, 830, 10)),
                self._cmfs,
                self._A,
                use_practice_range=False,
            ),
            np.array([14.47773312, 10.86353641, 2.04750445]),
            decimal=7,
        )

        np.testing.assert_almost_equal(
            sd_to_XYZ_ASTME308(
                reshape_sd(self._sd, SpectralShape(400, 700, 10)),
                self._cmfs,
                self._A,
            ),
            np.array([14.54137532, 10.88641727, 2.04931318]),
            decimal=7,
        )

        np.testing.assert_almost_equal(
            sd_to_XYZ_ASTME308(
                reshape_sd(self._sd, SpectralShape(400, 700, 10)),
                self._cmfs,
                self._A,
                use_practice_range=False,
            ),
            np.array([14.54167211, 10.88649849, 2.04930374]),
            decimal=7,
        )

        np.testing.assert_almost_equal(
            sd_to_XYZ_ASTME308(
                reshape_sd(self._sd, SpectralShape(400, 700, 10)),
                self._cmfs,
                self._A,
                k=1,
            ),
            np.array([1568.94283333, 1174.59084705, 221.11080639]),
            decimal=7,
        )
Beispiel #6
0
    def test_sd_to_XYZ_tristimulus_weighting_factors_ASTME308(self):
        """
        Tests :func:`colour.colorimetry.tristimulus.\
sd_to_XYZ_tristimulus_weighting_factors_ASTME308`
        definition.
        """

        cmfs = CMFS['CIE 1931 2 Degree Standard Observer']
        np.testing.assert_almost_equal(
            sd_to_XYZ_tristimulus_weighting_factors_ASTME308(
                SAMPLE_SD, cmfs, ILLUMINANTS_SDS['A']),
            np.array([14.46366344, 10.85828513, 2.04663792]),
            decimal=7)

        cmfs = CMFS['CIE 1964 10 Degree Standard Observer']
        np.testing.assert_almost_equal(
            sd_to_XYZ_tristimulus_weighting_factors_ASTME308(
                SAMPLE_SD, cmfs, ILLUMINANTS_SDS['C']),
            np.array([10.77033881, 9.44864632, 6.62758924]),
            decimal=7)

        np.testing.assert_almost_equal(
            sd_to_XYZ_tristimulus_weighting_factors_ASTME308(
                SAMPLE_SD, cmfs, ILLUMINANTS_SDS['FL2']),
            np.array([11.57837130, 9.98734511, 3.95499522]),
            decimal=7)

        np.testing.assert_almost_equal(
            sd_to_XYZ_tristimulus_weighting_factors_ASTME308(
                SAMPLE_SD.copy().trim(SpectralShape(400, 700, 5)), cmfs,
                ILLUMINANTS_SDS['A']),
            np.array([14.38180830, 10.74512906, 2.01579131]),
            decimal=7)

        np.testing.assert_almost_equal(
            sd_to_XYZ_tristimulus_weighting_factors_ASTME308(
                SAMPLE_SD.copy().interpolate(SpectralShape(400, 700, 10)),
                cmfs, ILLUMINANTS_SDS['A']),
            np.array([14.38284399, 10.74577954, 2.01553721]),
            decimal=7)

        np.testing.assert_almost_equal(
            sd_to_XYZ_tristimulus_weighting_factors_ASTME308(
                SAMPLE_SD.copy().interpolate(SpectralShape(400, 700, 20)),
                cmfs, ILLUMINANTS_SDS['A']),
            np.array([14.38356848, 10.74613294, 2.01526418]),
            decimal=7)

        np.testing.assert_almost_equal(
            sd_to_XYZ_tristimulus_weighting_factors_ASTME308(
                SAMPLE_SD.copy().interpolate(SpectralShape(400, 700, 20)),
                cmfs,
                ILLUMINANTS_SDS['A'],
                k=1),
            np.array([1636.74286798, 1222.82981953, 229.32204062]),
            decimal=7)
Beispiel #7
0
    def test_sd_to_XYZ_tristimulus_weighting_factors_ASTME308(self):
        """
        Tests :func:`colour.colorimetry.tristimulus.\
sd_to_XYZ_tristimulus_weighting_factors_ASTME308`
        definition.
        """

        cmfs = MSDS_CMFS['CIE 1931 2 Degree Standard Observer']
        np.testing.assert_almost_equal(
            sd_to_XYZ_tristimulus_weighting_factors_ASTME308(
                SD_SAMPLE, cmfs, SDS_ILLUMINANTS['A']),
            np.array([14.46341867, 10.85820227, 2.04697034]),
            decimal=7)

        cmfs = MSDS_CMFS['CIE 1964 10 Degree Standard Observer']
        np.testing.assert_almost_equal(
            sd_to_XYZ_tristimulus_weighting_factors_ASTME308(
                SD_SAMPLE, cmfs, SDS_ILLUMINANTS['C']),
            np.array([10.77005571, 9.44877491, 6.62428210]),
            decimal=7)

        np.testing.assert_almost_equal(
            sd_to_XYZ_tristimulus_weighting_factors_ASTME308(
                SD_SAMPLE, cmfs, SDS_ILLUMINANTS['FL2']),
            np.array([11.57542759, 9.98605604, 3.95273304]),
            decimal=7)

        np.testing.assert_almost_equal(
            sd_to_XYZ_tristimulus_weighting_factors_ASTME308(
                SD_SAMPLE.copy().trim(SpectralShape(400, 700, 5)), cmfs,
                SDS_ILLUMINANTS['A']),
            np.array([14.38153638, 10.74503131, 2.01613844]),
            decimal=7)

        np.testing.assert_almost_equal(
            sd_to_XYZ_tristimulus_weighting_factors_ASTME308(
                SD_SAMPLE.copy().interpolate(SpectralShape(400, 700, 10)),
                cmfs, SDS_ILLUMINANTS['A']),
            np.array([14.38257202, 10.74568178, 2.01588427]),
            decimal=7)

        np.testing.assert_almost_equal(
            sd_to_XYZ_tristimulus_weighting_factors_ASTME308(
                SD_SAMPLE.copy().interpolate(SpectralShape(400, 700, 20)),
                cmfs, SDS_ILLUMINANTS['A']),
            np.array([14.38329645, 10.74603515, 2.01561113]),
            decimal=7)

        np.testing.assert_almost_equal(
            sd_to_XYZ_tristimulus_weighting_factors_ASTME308(
                SD_SAMPLE.copy().interpolate(SpectralShape(400, 700, 20)),
                cmfs,
                SDS_ILLUMINANTS['A'],
                k=1),
            np.array([1636.74881983, 1222.84626486, 229.36669308]),
            decimal=7)
Beispiel #8
0
def mesopic_luminous_efficiency_function(
        Lp,
        source='Blue Heavy',
        method='MOVE',
        photopic_lef=PHOTOPIC_LEFS['CIE 1924 Photopic Standard Observer'],
        scotopic_lef=SCOTOPIC_LEFS['CIE 1951 Scotopic Standard Observer']):
    """
    Returns the mesopic luminous efficiency function :math:`V_m(\lambda)` for
    given photopic luminance :math:`L_p`.

    Parameters
    ----------
    Lp : numeric
        Photopic luminance :math:`L_p`.
    source : unicode, optional
        **{'Blue Heavy', 'Red Heavy'}**,
        Light source colour temperature.
    method : unicode, optional
        **{'MOVE', 'LRC'}**,
        Method to calculate the weighting factor.
    photopic_lef : SpectralPowerDistribution, optional
        :math:`V(\lambda)` photopic luminous efficiency function.
    scotopic_lef : SpectralPowerDistribution, optional
        :math:`V^\prime(\lambda)` scotopic luminous efficiency function.

    Returns
    -------
    SpectralPowerDistribution
        Mesopic luminous efficiency function :math:`V_m(\lambda)`.

    Examples
    --------
    >>> print(mesopic_luminous_efficiency_function(0.2))
    SpectralPowerDistribution(\
'0.2 Lp Mesopic Luminous Efficiency Function', (380.0, 780.0, 1.0))
    """

    photopic_lef_shape = photopic_lef.shape
    scotopic_lef_shape = scotopic_lef.shape
    shape = SpectralShape(
        max(photopic_lef_shape.start, scotopic_lef_shape.start),
        min(photopic_lef_shape.end, scotopic_lef_shape.end),
        max(photopic_lef_shape.interval, scotopic_lef_shape.interval))

    wavelengths = shape.range()

    spd_data = dict(
        zip(
            wavelengths,
            mesopic_weighting_function(wavelengths, Lp, source, method,
                                       photopic_lef, scotopic_lef)))

    spd = SpectralPowerDistribution(
        '{0} Lp Mesopic Luminous Efficiency Function'.format(Lp), spd_data)

    return spd.normalise()
Beispiel #9
0
    def test_sd_to_XYZ_ASTME308_mi_1nm(self):
        """
        Test :func:`colour.colorimetry.tristimulus_values.sd_to_XYZ_ASTME308`
        definition for 1 nm measurement intervals.
        """

        np.testing.assert_almost_equal(
            sd_to_XYZ_ASTME308(reshape_sd(self._sd, self._cmfs.shape),
                               self._cmfs, self._A),
            np.array([14.46372680, 10.85832950, 2.04663200]),
            decimal=7,
        )

        np.testing.assert_almost_equal(
            sd_to_XYZ_ASTME308(
                reshape_sd(self._sd, self._cmfs.shape),
                self._cmfs,
                self._A,
                use_practice_range=False,
            ),
            np.array([14.46366018, 10.85827949, 2.04662258]),
            decimal=7,
        )

        np.testing.assert_almost_equal(
            sd_to_XYZ_ASTME308(
                reshape_sd(self._sd, SpectralShape(400, 700, 1)),
                self._cmfs,
                self._A,
            ),
            np.array([14.54173397, 10.88628632, 2.04965822]),
            decimal=7,
        )

        np.testing.assert_almost_equal(
            sd_to_XYZ_ASTME308(
                reshape_sd(self._sd, SpectralShape(400, 700, 1)),
                self._cmfs,
                self._A,
                use_practice_range=False,
            ),
            np.array([14.54203076, 10.88636754, 2.04964877]),
            decimal=7,
        )

        np.testing.assert_almost_equal(
            sd_to_XYZ_ASTME308(
                reshape_sd(self._sd, SpectralShape(400, 700, 1)),
                self._cmfs,
                self._A,
                k=1,
            ),
            np.array([1568.98152997, 1174.57671769, 221.14803420]),
            decimal=7,
        )
Beispiel #10
0
    def test_raise_exception_colour_fidelity_index_CFI2017(self):
        """
        Test :func:`colour.quality.CIE2017.colour_fidelity_index_CFI2017`
        definition raised exception.
        """

        sd = reshape_sd(SDS_ILLUMINANTS["FL2"], SpectralShape(400, 700, 5))
        self.assertWarns(ColourUsageWarning, colour_fidelity_index_CIE2017, sd)

        sd = reshape_sd(SDS_ILLUMINANTS["FL2"], SpectralShape(380, 780, 10))
        self.assertRaises(ValueError, colour_fidelity_index_CIE2017, sd)
Beispiel #11
0
def mesopic_luminous_efficiency_function(
    Lp,
    source="Blue Heavy",
    method="MOVE",
    photopic_lef=PHOTOPIC_LEFS.get("CIE 1924 Photopic Standard Observer"),
    scotopic_lef=SCOTOPIC_LEFS.get("CIE 1951 Scotopic Standard Observer"),
):
    """
    Returns the mesopic luminous efficiency function :math:`V_m(\lambda)` for
    given photopic luminance :math:`L_p`.

    Parameters
    ----------
    Lp : numeric
        Photopic luminance :math:`L_p`.
    source : unicode, optional
        **{'Blue Heavy', 'Red Heavy'}**,
        Light source colour temperature.
    method : unicode, optional
        **{'MOVE', 'LRC'}**,
        Method to calculate the weighting factor.
    photopic_lef : SpectralPowerDistribution, optional
        :math:`V(\lambda)` photopic luminous efficiency function.
    scotopic_lef : SpectralPowerDistribution, optional
        :math:`V^\prime(\lambda)` scotopic luminous efficiency function.

    Returns
    -------
    SpectralPowerDistribution
        Mesopic luminous efficiency function :math:`V_m(\lambda)`.

    Examples
    --------
    >>> mesopic_luminous_efficiency_function(0.2)  # doctest: +ELLIPSIS
    <colour.colorimetry.spectrum.SpectralPowerDistribution object at 0x...>
    """

    photopic_lef_shape = photopic_lef.shape
    scotopic_lef_shape = scotopic_lef.shape
    shape = SpectralShape(
        max(photopic_lef_shape.start, scotopic_lef_shape.start),
        min(photopic_lef_shape.end, scotopic_lef_shape.end),
        max(photopic_lef_shape.steps, scotopic_lef_shape.steps),
    )

    wavelengths = shape.range()

    spd_data = dict(
        zip(wavelengths, mesopic_weighting_function(wavelengths, Lp, source, method, photopic_lef, scotopic_lef))
    )

    spd = SpectralPowerDistribution("{0} Lp Mesopic Luminous Efficiency Function".format(Lp), spd_data)

    return spd.normalise()
Beispiel #12
0
    def test_adjust_tristimulus_weighting_factors_ASTME30815(self):
        """
        Tests :func:`colour.colorimetry.tristimulus.\
adjust_tristimulus_weighting_factors_ASTME30815` definition.
        """

        np.testing.assert_almost_equal(
            adjust_tristimulus_weighting_factors_ASTME30815(
                D65_CIE_1931_2_20_TWF, SpectralShape(360, 830, 20),
                SpectralShape(400, 700, 20)),
            D65_CIE_1931_2_20_ATWF,
            decimal=3)
Beispiel #13
0
    def test_XYZ_to_sd_Meng2015(self):
        """
        Tests :func:`colour.recovery.meng2015.XYZ_to_sd_Meng2015`
        definition.
        """

        cmfs = (STANDARD_OBSERVERS_CMFS['CIE 1931 2 Degree Standard Observer'].
                copy().trim(DEFAULT_SPECTRAL_SHAPE))
        shape = SpectralShape(cmfs.shape.start, cmfs.shape.end, 5)
        cmfs_c = cmfs.copy().align(shape)

        XYZ = np.array([0.21781186, 0.12541048, 0.04697113])
        np.testing.assert_almost_equal(
            sd_to_XYZ_integration(XYZ_to_sd_Meng2015(XYZ, cmfs_c), cmfs_c) /
            100,
            XYZ,
            decimal=7)

        shape = SpectralShape(cmfs.shape.start, cmfs.shape.end, 10)
        cmfs_c = cmfs.copy().align(shape)

        np.testing.assert_almost_equal(
            sd_to_XYZ_integration(XYZ_to_sd_Meng2015(XYZ, cmfs_c), cmfs_c) /
            100,
            XYZ,
            decimal=7)

        np.testing.assert_almost_equal(sd_to_XYZ_integration(
            XYZ_to_sd_Meng2015(XYZ, cmfs_c, ILLUMINANTS_SDS['D65']), cmfs_c,
            ILLUMINANTS_SDS['D65']) / 100,
                                       XYZ,
                                       decimal=7)

        np.testing.assert_almost_equal(sd_to_XYZ_integration(
            XYZ_to_sd_Meng2015(
                XYZ,
                cmfs_c,
                optimisation_parameters={'options': {
                    'ftol': 1e-10,
                }}), cmfs_c) / 100,
                                       XYZ,
                                       decimal=7)

        shape = SpectralShape(400, 700, 5)
        cmfs_c = cmfs.copy().align(shape)
        np.testing.assert_almost_equal(
            sd_to_XYZ_integration(XYZ_to_sd_Meng2015(XYZ, cmfs_c), cmfs_c) /
            100,
            XYZ,
            decimal=7)
Beispiel #14
0
    def test_raise_exception_colour_fidelity_index_CFI2017(self):
        """
        Tests :func:`colour.quality.CIE2017.colour_fidelity_index_CFI2017`
        definition raised exception.
        """

        if six.PY3:  # pragma: no cover
            sd = SDS_ILLUMINANTS['FL2'].copy().align(SpectralShape(
                400, 700, 5))
            self.assertWarns(ColourUsageWarning, colour_fidelity_index_CIE2017,
                             sd)

        sd = SDS_ILLUMINANTS['FL2'].copy().align(SpectralShape(380, 780, 10))
        self.assertRaises(ValueError, colour_fidelity_index_CIE2017, sd)
Beispiel #15
0
    def test_adjust_tristimulus_weighting_factors_ASTME308(self):
        """
        Test :func:`colour.colorimetry.tristimulus_values.\
adjust_tristimulus_weighting_factors_ASTME308` definition.
        """

        np.testing.assert_almost_equal(
            adjust_tristimulus_weighting_factors_ASTME308(
                TWF_D65_CIE_1931_2_20,
                SpectralShape(360, 830, 20),
                SpectralShape(400, 700, 20),
            ),
            TWF_D65_CIE_1931_2_20_A,
            decimal=3,
        )
Beispiel #16
0
    def test_tristimulus_weighting_factors_ASTME2022(self):
        """
        Tests :func:`colour.colorimetry.tristimulus.\
tristimulus_weighting_factors_ASTME2022` definition.

        Notes
        -----
        -   :attr:`TWF_A_CIE_1964_10_10`, :attr:`TWF_A_CIE_1964_10_20` and
            :attr:`TWF_D65_CIE_1931_2_20` attributes data is matching
            :cite:`ASTMInternational2015b`.

        References
        ----------
        :cite:`ASTMInternational2015b`
        """

        cmfs = MSDS_CMFS['CIE 1964 10 Degree Standard Observer']
        A = sd_CIE_standard_illuminant_A(cmfs.shape)

        twf = tristimulus_weighting_factors_ASTME2022(
            cmfs, A, SpectralShape(360, 830, 10))
        np.testing.assert_almost_equal(np.round(twf, 3),
                                       TWF_A_CIE_1964_10_10,
                                       decimal=3)

        twf = tristimulus_weighting_factors_ASTME2022(
            cmfs, A, SpectralShape(360, 830, 20))
        np.testing.assert_almost_equal(np.round(twf, 3),
                                       TWF_A_CIE_1964_10_20,
                                       decimal=3)

        cmfs = MSDS_CMFS['CIE 1931 2 Degree Standard Observer']
        D65 = SDS_ILLUMINANTS['D65'].copy().align(
            cmfs.shape, interpolator=LinearInterpolator)
        twf = tristimulus_weighting_factors_ASTME2022(
            cmfs, D65, SpectralShape(360, 830, 20))
        np.testing.assert_almost_equal(np.round(twf, 3),
                                       TWF_D65_CIE_1931_2_20,
                                       decimal=3)

        twf = tristimulus_weighting_factors_ASTME2022(cmfs,
                                                      D65,
                                                      SpectralShape(
                                                          360, 830, 20),
                                                      k=1)
        np.testing.assert_almost_equal(twf,
                                       TWF_D65_CIE_1931_2_20_K1,
                                       decimal=7)
Beispiel #17
0
    def test_raise_exception_tristimulus_weighting_factors_ASTME2022(self):
        """
        Test :func:`colour.colorimetry.tristimulus_values.\
tristimulus_weighting_factors_ASTME2022` definition raised exception.
        """

        shape = SpectralShape(360, 830, 10)
        cmfs_1 = MSDS_CMFS["CIE 1964 10 Degree Standard Observer"]
        # pylint: disable=E1102
        cmfs_2 = reshape_msds(cmfs_1, shape)
        A_1 = sd_CIE_standard_illuminant_A(cmfs_1.shape)
        A_2 = sd_CIE_standard_illuminant_A(cmfs_2.shape)

        self.assertRaises(
            ValueError,
            tristimulus_weighting_factors_ASTME2022,
            cmfs_1,
            A_2,
            shape,
        )

        self.assertRaises(
            ValueError,
            tristimulus_weighting_factors_ASTME2022,
            cmfs_2,
            A_1,
            shape,
        )
Beispiel #18
0
    def test_handle_spectral_arguments(self):
        """
        Test :func:`colour.colorimetry.tristimulus_values.\
handle_spectral_arguments` definition.
        """

        cmfs, illuminant = handle_spectral_arguments()
        # pylint: disable=E1102
        self.assertEqual(
            cmfs,
            reshape_msds(MSDS_CMFS["CIE 1931 2 Degree Standard Observer"]),
        )
        self.assertEqual(illuminant, reshape_sd(SDS_ILLUMINANTS["D65"]))

        shape = SpectralShape(400, 700, 20)
        cmfs, illuminant = handle_spectral_arguments(shape_default=shape)
        self.assertEqual(cmfs.shape, shape)
        self.assertEqual(illuminant.shape, shape)

        cmfs, illuminant = handle_spectral_arguments(
            cmfs_default="CIE 2012 2 Degree Standard Observer",
            illuminant_default="E",
            shape_default=shape,
        )
        self.assertEqual(
            cmfs,
            reshape_msds(MSDS_CMFS["CIE 2012 2 Degree Standard Observer"],
                         shape=shape),
        )
        self.assertEqual(illuminant,
                         sd_ones(shape, interpolator=LinearInterpolator) * 100)
Beispiel #19
0
def sd_Jakob2019(
    coefficients: ArrayLike, shape: SpectralShape = SPECTRAL_SHAPE_JAKOB2019
) -> SpectralDistribution:
    """
    Return a spectral distribution following the spectral model given by
    *Jakob and Hanika (2019)*.

    Parameters
    ----------
    coefficients
        Dimensionless coefficients for *Jakob and Hanika (2019)* reflectance
        spectral model.
    shape
        Shape used by the spectral distribution.

    Returns
    -------
    :class:`colour.SpectralDistribution`
        *Jakob and Hanika (2019)* spectral distribution.

    References
    ----------
    :cite:`Jakob2019`

    Examples
    --------
    >>> from colour.utilities import numpy_print_options
    >>> with numpy_print_options(suppress=True):
    ...     sd_Jakob2019([-9e-05, 8.5e-02, -20], SpectralShape(400, 700, 20))
    ...     # doctest: +ELLIPSIS
    SpectralDistribution([[ 400.        ,    0.3143046...],
                          [ 420.        ,    0.4133320...],
                          [ 440.        ,    0.4880034...],
                          [ 460.        ,    0.5279562...],
                          [ 480.        ,    0.5319346...],
                          [ 500.        ,    0.5      ...],
                          [ 520.        ,    0.4326202...],
                          [ 540.        ,    0.3373544...],
                          [ 560.        ,    0.2353056...],
                          [ 580.        ,    0.1507665...],
                          [ 600.        ,    0.0931332...],
                          [ 620.        ,    0.0577434...],
                          [ 640.        ,    0.0367011...],
                          [ 660.        ,    0.0240879...],
                          [ 680.        ,    0.0163316...],
                          [ 700.        ,    0.0114118...]],
                         interpolator=SpragueInterpolator,
                         interpolator_kwargs={},
                         extrapolator=Extrapolator,
                         extrapolator_kwargs={...})
    """

    c_0, c_1, c_2 = as_float_array(coefficients)
    wl = shape.range()
    U = c_0 * wl**2 + c_1 * wl + c_2
    R = 1 / 2 + U / (2 * np.sqrt(1 + U**2))

    name = f"{coefficients!r} (COEFF) - Jakob (2019)"

    return SpectralDistribution(R, wl, name=name)
Beispiel #20
0
    def test_XYZ_to_sd_Meng2015(self):
        """
        Tests :func:`colour.recovery.meng2015.XYZ_to_sd_Meng2015`
        definition.
        """

        cmfs = STANDARD_OBSERVERS_CMFS['CIE 1931 2 Degree Standard Observer']
        shape = SpectralShape(cmfs.shape.start, cmfs.shape.end, 5)
        cmfs_c = cmfs.copy().align(shape)

        XYZ = np.array([0.21781186, 0.12541048, 0.04697113])
        np.testing.assert_almost_equal(
            sd_to_XYZ_integration(XYZ_to_sd_Meng2015(XYZ), cmfs=cmfs_c) / 100,
            XYZ,
            decimal=7)

        shape = SpectralShape(cmfs.shape.start, cmfs.shape.end, 10)
        cmfs_c = cmfs.copy().align(shape)

        np.testing.assert_almost_equal(
            sd_to_XYZ_integration(
                XYZ_to_sd_Meng2015(XYZ, interval=10), cmfs=cmfs_c) / 100,
            XYZ,
            decimal=7)

        np.testing.assert_almost_equal(
            sd_to_XYZ_integration(
                XYZ_to_sd_Meng2015(
                    XYZ,
                    interval=10,
                    optimisation_parameters={
                        'options': {
                            'ftol': 1e-10,
                            'maxiter': 2000
                        }
                    }),
                cmfs=cmfs_c) / 100,
            XYZ,
            decimal=7)

        shape = SpectralShape(400, 700, 5)
        cmfs_c = cmfs.copy().align(shape)
        np.testing.assert_almost_equal(
            sd_to_XYZ_integration(
                XYZ_to_sd_Meng2015(XYZ, cmfs=cmfs_c), cmfs=cmfs_c) / 100,
            XYZ,
            decimal=7)
Beispiel #21
0
    def test_tristimulus_weighting_factors_ASTME202211(self):
        """
        Tests :func:`colour.colorimetry.tristimulus.\
tristimulus_weighting_factors_ASTME202211` definition.

        Notes
        -----
        :attr:`A_CIE_1964_10_10_TWF`, :attr:`A_CIE_1964_10_20_TWF` and
        :attr:`D65_CIE_1931_2_20_TWF` attributes data is matching [1]_.

        References
        ----------
        .. [1]  ASTM International. (2015). ASTM E308–15 - Standard Practice
                for Computing the Colors of Objects by Using the CIE System,
                1–47. doi:10.1520/E0308-15
        """

        cmfs = CMFS.get('CIE 1964 10 Degree Standard Observer')
        wl = cmfs.shape.range()
        A = SpectralPowerDistribution(
            'A (360, 830, 1)',
            dict(zip(wl, CIE_standard_illuminant_A_function(wl))))

        twf = tristimulus_weighting_factors_ASTME202211(
            cmfs, A, SpectralShape(360, 830, 10))
        np.testing.assert_almost_equal(
            np.round(twf, 3),
            A_CIE_1964_10_10_TWF,
            decimal=3)

        twf = tristimulus_weighting_factors_ASTME202211(
            cmfs, A, SpectralShape(360, 830, 20))
        np.testing.assert_almost_equal(
            np.round(twf, 3),
            A_CIE_1964_10_20_TWF,
            decimal=3)

        cmfs = CMFS.get('CIE 1931 2 Degree Standard Observer')
        D65 = ILLUMINANTS_RELATIVE_SPDS['D65'].clone().align(
            cmfs.shape, interpolation_method='Linear')
        twf = tristimulus_weighting_factors_ASTME202211(
            cmfs, D65, SpectralShape(360, 830, 20))
        np.testing.assert_almost_equal(
            np.round(twf, 3),
            D65_CIE_1931_2_20_TWF,
            decimal=3)
Beispiel #22
0
    def test_raise_exception_sd_to_XYZ_ASTME308(self):
        """
        Tests :func:`colour.colorimetry.tristimulus.sd_to_XYZ_ASTME308`
        definition raised exception.
        """

        self.assertRaises(ValueError, sd_to_XYZ_ASTME308,
                          self._sd.copy().align(SpectralShape(360, 820, 2)))
Beispiel #23
0
    def test_XYZ_to_sd_Meng2015(self):
        """Test :func:`colour.recovery.meng2015.XYZ_to_sd_Meng2015` definition."""

        XYZ = np.array([0.20654008, 0.12197225, 0.05136952])
        np.testing.assert_almost_equal(
            sd_to_XYZ_integration(
                XYZ_to_sd_Meng2015(XYZ, self._cmfs, self._sd_D65),
                self._cmfs,
                self._sd_D65,
            )
            / 100,
            XYZ,
            decimal=7,
        )

        np.testing.assert_almost_equal(
            sd_to_XYZ_integration(
                XYZ_to_sd_Meng2015(XYZ, self._cmfs, self._sd_E),
                self._cmfs,
                self._sd_E,
            )
            / 100,
            XYZ,
            decimal=7,
        )

        np.testing.assert_almost_equal(
            sd_to_XYZ_integration(
                XYZ_to_sd_Meng2015(
                    XYZ,
                    self._cmfs,
                    self._sd_D65,
                    optimisation_kwargs={
                        "options": {
                            "ftol": 1e-10,
                        }
                    },
                ),
                self._cmfs,
                self._sd_D65,
            )
            / 100,
            XYZ,
            decimal=7,
        )

        shape = SpectralShape(400, 700, 5)
        # pylint: disable=E1102
        cmfs = reshape_msds(self._cmfs, shape)
        np.testing.assert_almost_equal(
            sd_to_XYZ_integration(
                XYZ_to_sd_Meng2015(XYZ, cmfs, self._sd_D65), cmfs, self._sd_D65
            )
            / 100,
            XYZ,
            decimal=7,
        )
Beispiel #24
0
def msds_constant(
    k: Floating,
    labels: Sequence,
    shape: SpectralShape = SPECTRAL_SHAPE_DEFAULT,
    **kwargs: Any,
) -> MultiSpectralDistributions:
    """
    Return the multi-spectral distributions with given labels and given
    spectral shape filled with constant :math:`k` values.

    Parameters
    ----------
    k
        Constant :math:`k` to fill the multi-spectral distributions with.
    labels
        Names to use for the :class:`colour.SpectralDistribution` class
        instances.
    shape
        Spectral shape used to create the multi-spectral distributions.

    Other Parameters
    ----------------
    kwargs
        {:class:`colour.MultiSpectralDistributions`},
        See the documentation of the previously listed class.

    Returns
    -------
    :class:`colour.MultiSpectralDistributions`
        Constant :math:`k` filled multi-spectral distributions.

    Notes
    -----
    -   By default, the multi-spectral distributions will use the shape given
        by :attr:`colour.SPECTRAL_SHAPE_DEFAULT` attribute.

    Examples
    --------
    >>> msds = msds_constant(100, labels=['a', 'b', 'c'])
    >>> msds.shape
    SpectralShape(360.0, 780.0, 1.0)
    >>> msds[400]
    array([ 100.,  100.,  100.])
    >>> msds.labels  # doctest: +SKIP
    ['a', 'b', 'c']
    """

    settings = {"name": f"{k} Constant"}
    settings.update(kwargs)

    wavelengths = shape.range()
    values = full((len(wavelengths), len(labels)), k)

    return MultiSpectralDistributions(values,
                                      wavelengths,
                                      labels=labels,
                                      **settings)
Beispiel #25
0
def sd_gaussian_fwhm(
    peak_wavelength: Floating,
    fwhm: Floating,
    shape: SpectralShape = SPECTRAL_SHAPE_DEFAULT,
    **kwargs: Any,
) -> SpectralDistribution:
    """
    Return a gaussian spectral distribution of given spectral shape at given
    peak wavelength and full width at half maximum.

    Parameters
    ----------
    peak_wavelength
        Wavelength the gaussian spectral distribution will peak at.
    fwhm
        Full width at half maximum, i.e. width of the gaussian spectral
        distribution measured between those points on the *y* axis which are
        half the maximum amplitude.
    shape
        Spectral shape used to create the spectral distribution.

    Other Parameters
    ----------------
    kwargs
        {:class:`colour.SpectralDistribution`},
        See the documentation of the previously listed class.

    Returns
    -------
    :class:`colour.SpectralDistribution`
        Gaussian spectral distribution.

    Notes
    -----
    -   By default, the spectral distribution will use the shape given by
        :attr:`colour.SPECTRAL_SHAPE_DEFAULT` attribute.

    Examples
    --------
    >>> sd = sd_gaussian_fwhm(555, 25)
    >>> sd.shape
    SpectralShape(360.0, 780.0, 1.0)
    >>> sd[555]
    1.0
    >>> sd[530]  # doctest: +ELLIPSIS
    0.3678794...
    """

    settings = {"name": f"{peak_wavelength}nm - {fwhm} FWHM - Gaussian"}
    settings.update(kwargs)

    wavelengths = shape.range()

    values = np.exp(-(((wavelengths - peak_wavelength) / fwhm)**2))

    return SpectralDistribution(values, wavelengths, **settings)
Beispiel #26
0
    def setUp(self):
        """
        Initialises common tests attributes.
        """

        self._cmfs = MSDS_CMFS_STANDARD_OBSERVER[
            'CIE 1931 2 Degree Standard Observer'].copy().align(
                SpectralShape(360, 780, 10))
        self._sd_D65 = SDS_ILLUMINANTS['D65'].copy().align(self._cmfs.shape)
        self._sd_E = SDS_ILLUMINANTS['E'].copy().align(self._cmfs.shape)
Beispiel #27
0
    def test_sd_CIE_standard_illuminant_A(self):
        """
        Tests :func:`colour.colorimetry.illuminants.\
sd_CIE_standard_illuminant_A` definition.
        """

        np.testing.assert_almost_equal(sd_CIE_standard_illuminant_A(
            SpectralShape(360, 830, 5)).values,
                                       A_DATA,
                                       decimal=7)
Beispiel #28
0
    def setUp(self):
        """Initialise the common tests attributes."""

        # pylint: disable=E1102
        self._cmfs = reshape_msds(
            MSDS_CMFS["CIE 1931 2 Degree Standard Observer"],
            SpectralShape(360, 780, 10),
        )
        self._sd_D65 = reshape_sd(SDS_ILLUMINANTS["D65"], self._cmfs.shape)
        self._sd_E = reshape_sd(SDS_ILLUMINANTS["E"], self._cmfs.shape)
Beispiel #29
0
def matrix_anomalous_trichromacy_Machado2009(cmfs, primaries, d_LMS):
    """
    Computes the *Machado et al. (2009)* *CVD* matrix for given *LMS* cone
    fundamentals colour matching functions and display primaries tri-spectral
    distributions with given :math:`\\Delta_{LMS}` shift amount in nanometers
    to simulate anomalous trichromacy.

    Parameters
    ----------
    cmfs : LMS_ConeFundamentals
        *LMS* cone fundamentals colour matching functions.
    primaries : RGB_DisplayPrimaries
        *RGB* display primaries tri-spectral distributions.
    d_LMS : array_like
        :math:`\\Delta_{LMS}` shift amount in nanometers.

    Notes
    -----
    -   Input *LMS* cone fundamentals colour matching functions interval is
        expected to be 1 nanometer, incompatible input will be interpolated
        at 1 nanometer interval.
    -   Input :math:`\\Delta_{LMS}` shift amount is in domain [0, 20].

    Returns
    -------
    ndarray
        Anomalous trichromacy matrix.

    References
    ----------
    :cite:`Colblindorb`, :cite:`Colblindora`, :cite:`Colblindorc`,
    :cite:`Machado2009`

    Examples
    --------
    >>> from colour.characterisation import MSDS_DISPLAY_PRIMARIES
    >>> from colour.colorimetry import MSDS_CMFS_LMS
    >>> cmfs = MSDS_CMFS_LMS['Stockman & Sharpe 2 Degree Cone Fundamentals']
    >>> d_LMS = np.array([15, 0, 0])
    >>> primaries = MSDS_DISPLAY_PRIMARIES['Apple Studio Display']
    >>> matrix_anomalous_trichromacy_Machado2009(cmfs, primaries, d_LMS)
    ... # doctest: +ELLIPSIS
    array([[-0.2777465...,  2.6515008..., -1.3737543...],
           [ 0.2718936...,  0.2004786...,  0.5276276...],
           [ 0.0064404...,  0.2592157...,  0.7343437...]])
    """

    if cmfs.shape.interval != 1:
        cmfs = cmfs.copy().interpolate(SpectralShape(interval=1))

    M_n = matrix_RGB_to_WSYBRG(cmfs, primaries)
    cmfs_a = msds_cmfs_anomalous_trichromacy_Machado2009(cmfs, d_LMS)
    M_a = matrix_RGB_to_WSYBRG(cmfs_a, primaries)

    return matrix_dot(np.linalg.inv(M_n), M_a)
Beispiel #30
0
def sd_gaussian_normal(
    mu: Floating,
    sigma: Floating,
    shape: SpectralShape = SPECTRAL_SHAPE_DEFAULT,
    **kwargs: Any,
) -> SpectralDistribution:
    """
    Return a gaussian spectral distribution of given spectral shape at
    given mean wavelength :math:`\\mu` and standard deviation :math:`sigma`.

    Parameters
    ----------
    mu
        Mean wavelength :math:`\\mu` the gaussian spectral distribution will
        peak at.
    sigma
        Standard deviation :math:`sigma` of the gaussian spectral distribution.
    shape
        Spectral shape used to create the spectral distribution.

    Other Parameters
    ----------------
    kwargs
        {:class:`colour.SpectralDistribution`},
        See the documentation of the previously listed class.

    Returns
    -------
    :class:`colour.SpectralDistribution`
        Gaussian spectral distribution.

    Notes
    -----
    -   By default, the spectral distribution will use the shape given by
        :attr:`colour.SPECTRAL_SHAPE_DEFAULT` attribute.

    Examples
    --------
    >>> sd = sd_gaussian_normal(555, 25)
    >>> sd.shape
    SpectralShape(360.0, 780.0, 1.0)
    >>> sd[555]  # doctest: +ELLIPSIS
    1.0000000...
    >>> sd[530]  # doctest: +ELLIPSIS
    0.6065306...
    """

    settings = {"name": f"{mu}nm - {sigma} Sigma - Gaussian"}
    settings.update(kwargs)

    wavelengths = shape.range()

    values = np.exp(-((wavelengths - mu)**2) / (2 * sigma**2))

    return SpectralDistribution(values, wavelengths, **settings)
Beispiel #31
0
    def test_tristimulus_weighting_factors_ASTME202211(self):
        """
        Tests :func:`colour.colorimetry.tristimulus.\
tristimulus_weighting_factors_ASTME202211` definition.

        Notes
        -----
        :attr:`A_CIE_1964_10_10_TWF`, :attr:`A_CIE_1964_10_20_TWF` and
        :attr:`D65_CIE_1931_2_20_TWF` attributes data is matching
        :cite:`ASTMInternational2015b`.

        References
        ----------
        -   :cite:`ASTMInternational2015b`
        """

        cmfs = CMFS['CIE 1964 10 Degree Standard Observer']
        wl = cmfs.shape.range()
        A = SpectralPowerDistribution(dict(
            zip(wl, CIE_standard_illuminant_A_function(wl))),
                                      name='A (360, 830, 1)')

        twf = tristimulus_weighting_factors_ASTME202211(
            cmfs, A, SpectralShape(360, 830, 10))
        np.testing.assert_almost_equal(np.round(twf, 3),
                                       A_CIE_1964_10_10_TWF,
                                       decimal=3)

        twf = tristimulus_weighting_factors_ASTME202211(
            cmfs, A, SpectralShape(360, 830, 20))
        np.testing.assert_almost_equal(np.round(twf, 3),
                                       A_CIE_1964_10_20_TWF,
                                       decimal=3)

        cmfs = CMFS['CIE 1931 2 Degree Standard Observer']
        D65 = ILLUMINANTS_RELATIVE_SPDS['D65'].copy().align(
            cmfs.shape, interpolator=LinearInterpolator)
        twf = tristimulus_weighting_factors_ASTME202211(
            cmfs, D65, SpectralShape(360, 830, 20))
        np.testing.assert_almost_equal(np.round(twf, 3),
                                       D65_CIE_1931_2_20_TWF,
                                       decimal=3)
Beispiel #32
0
def sd_mesopic_luminous_efficiency_function(
        Lp,
        source='Blue Heavy',
        method='MOVE',
        photopic_lef=PHOTOPIC_LEFS['CIE 1924 Photopic Standard Observer'],
        scotopic_lef=SCOTOPIC_LEFS['CIE 1951 Scotopic Standard Observer']):
    """
    Returns the mesopic luminous efficiency function :math:`V_m(\\lambda)` for
    given photopic luminance :math:`L_p`.

    Parameters
    ----------
    Lp : numeric
        Photopic luminance :math:`L_p`.
    source : unicode, optional
        **{'Blue Heavy', 'Red Heavy'}**,
        Light source colour temperature.
    method : unicode, optional
        **{'MOVE', 'LRC'}**,
        Method to calculate the weighting factor.
    photopic_lef : SpectralDistribution, optional
        :math:`V(\\lambda)` photopic luminous efficiency function.
    scotopic_lef : SpectralDistribution, optional
        :math:`V^\\prime(\\lambda)` scotopic luminous efficiency function.

    Returns
    -------
    SpectralDistribution
        Mesopic luminous efficiency function :math:`V_m(\\lambda)`.

    References
    ----------
    :cite:`Wikipedia2005d`

    Examples
    --------
    >>> from colour.utilities import numpy_print_options
    >>> with numpy_print_options(suppress=True):
    ...     sd_mesopic_luminous_efficiency_function(0.2)  # doctest: +ELLIPSIS
    SpectralDistribution([[ 380.        ,    0.000424 ...],
                          [ 381.        ,    0.0004781...],
                          [ 382.        ,    0.0005399...],
                          [ 383.        ,    0.0006122...],
                          [ 384.        ,    0.0006961...],
                          [ 385.        ,    0.0007929...],
                          [ 386.        ,    0.000907 ...],
                          [ 387.        ,    0.0010389...],
                          [ 388.        ,    0.0011923...],
                          [ 389.        ,    0.0013703...],
                          [ 390.        ,    0.0015771...],
                          [ 391.        ,    0.0018167...],
                          [ 392.        ,    0.0020942...],
                          [ 393.        ,    0.0024160...],
                          [ 394.        ,    0.0027888...],
                          [ 395.        ,    0.0032196...],
                          [ 396.        ,    0.0037222...],
                          [ 397.        ,    0.0042957...],
                          [ 398.        ,    0.0049531...],
                          [ 399.        ,    0.0057143...],
                          [ 400.        ,    0.0065784...],
                          [ 401.        ,    0.0075658...],
                          [ 402.        ,    0.0086912...],
                          [ 403.        ,    0.0099638...],
                          [ 404.        ,    0.0114058...],
                          [ 405.        ,    0.0130401...],
                          [ 406.        ,    0.0148750...],
                          [ 407.        ,    0.0169310...],
                          [ 408.        ,    0.0192211...],
                          [ 409.        ,    0.0217511...],
                          [ 410.        ,    0.0245342...],
                          [ 411.        ,    0.0275773...],
                          [ 412.        ,    0.0309172...],
                          [ 413.        ,    0.0345149...],
                          [ 414.        ,    0.0383998...],
                          [ 415.        ,    0.0425744...],
                          [ 416.        ,    0.0471074...],
                          [ 417.        ,    0.0519322...],
                          [ 418.        ,    0.0570541...],
                          [ 419.        ,    0.0625466...],
                          [ 420.        ,    0.0683463...],
                          [ 421.        ,    0.0745255...],
                          [ 422.        ,    0.0809440...],
                          [ 423.        ,    0.0877344...],
                          [ 424.        ,    0.0948915...],
                          [ 425.        ,    0.1022731...],
                          [ 426.        ,    0.109877 ...],
                          [ 427.        ,    0.1178421...],
                          [ 428.        ,    0.1260316...],
                          [ 429.        ,    0.1343772...],
                          [ 430.        ,    0.143017 ...],
                          [ 431.        ,    0.1518128...],
                          [ 432.        ,    0.1608328...],
                          [ 433.        ,    0.1700088...],
                          [ 434.        ,    0.1792726...],
                          [ 435.        ,    0.1886934...],
                          [ 436.        ,    0.1982041...],
                          [ 437.        ,    0.2078032...],
                          [ 438.        ,    0.2174184...],
                          [ 439.        ,    0.2271147...],
                          [ 440.        ,    0.2368196...],
                          [ 441.        ,    0.2464623...],
                          [ 442.        ,    0.2561153...],
                          [ 443.        ,    0.2657160...],
                          [ 444.        ,    0.2753387...],
                          [ 445.        ,    0.2848520...],
                          [ 446.        ,    0.2944648...],
                          [ 447.        ,    0.3034902...],
                          [ 448.        ,    0.3132347...],
                          [ 449.        ,    0.3223257...],
                          [ 450.        ,    0.3314513...],
                          [ 451.        ,    0.3406129...],
                          [ 452.        ,    0.3498117...],
                          [ 453.        ,    0.3583617...],
                          [ 454.        ,    0.3676377...],
                          [ 455.        ,    0.3762670...],
                          [ 456.        ,    0.3849392...],
                          [ 457.        ,    0.3936540...],
                          [ 458.        ,    0.4024077...],
                          [ 459.        ,    0.4111965...],
                          [ 460.        ,    0.4193298...],
                          [ 461.        ,    0.4281803...],
                          [ 462.        ,    0.4363804...],
                          [ 463.        ,    0.4453117...],
                          [ 464.        ,    0.4542949...],
                          [ 465.        ,    0.4626509...],
                          [ 466.        ,    0.4717570...],
                          [ 467.        ,    0.4809300...],
                          [ 468.        ,    0.4901776...],
                          [ 469.        ,    0.4995075...],
                          [ 470.        ,    0.5096145...],
                          [ 471.        ,    0.5191293...],
                          [ 472.        ,    0.5294259...],
                          [ 473.        ,    0.5391316...],
                          [ 474.        ,    0.5496217...],
                          [ 475.        ,    0.5602103...],
                          [ 476.        ,    0.5702197...],
                          [ 477.        ,    0.5810207...],
                          [ 478.        ,    0.5919093...],
                          [ 479.        ,    0.6028683...],
                          [ 480.        ,    0.6138806...],
                          [ 481.        ,    0.6249373...],
                          [ 482.        ,    0.6360619...],
                          [ 483.        ,    0.6465989...],
                          [ 484.        ,    0.6579538...],
                          [ 485.        ,    0.6687841...],
                          [ 486.        ,    0.6797939...],
                          [ 487.        ,    0.6909887...],
                          [ 488.        ,    0.7023827...],
                          [ 489.        ,    0.7133032...],
                          [ 490.        ,    0.7244513...],
                          [ 491.        ,    0.7358470...],
                          [ 492.        ,    0.7468118...],
                          [ 493.        ,    0.7580294...],
                          [ 494.        ,    0.7694964...],
                          [ 495.        ,    0.7805225...],
                          [ 496.        ,    0.7917805...],
                          [ 497.        ,    0.8026123...],
                          [ 498.        ,    0.8130793...],
                          [ 499.        ,    0.8239297...],
                          [ 500.        ,    0.8352251...],
                          [ 501.        ,    0.8456342...],
                          [ 502.        ,    0.8564818...],
                          [ 503.        ,    0.8676921...],
                          [ 504.        ,    0.8785021...],
                          [ 505.        ,    0.8881489...],
                          [ 506.        ,    0.8986405...],
                          [ 507.        ,    0.9079322...],
                          [ 508.        ,    0.9174255...],
                          [ 509.        ,    0.9257739...],
                          [ 510.        ,    0.9350656...],
                          [ 511.        ,    0.9432365...],
                          [ 512.        ,    0.9509063...],
                          [ 513.        ,    0.9586931...],
                          [ 514.        ,    0.9658413...],
                          [ 515.        ,    0.9722825...],
                          [ 516.        ,    0.9779924...],
                          [ 517.        ,    0.9836106...],
                          [ 518.        ,    0.9883465...],
                          [ 519.        ,    0.9920964...],
                          [ 520.        ,    0.9954436...],
                          [ 521.        ,    0.9976202...],
                          [ 522.        ,    0.9993457...],
                          [ 523.        ,    1.       ...],
                          [ 524.        ,    0.9996498...],
                          [ 525.        ,    0.9990487...],
                          [ 526.        ,    0.9975356...],
                          [ 527.        ,    0.9957615...],
                          [ 528.        ,    0.9930143...],
                          [ 529.        ,    0.9899559...],
                          [ 530.        ,    0.9858741...],
                          [ 531.        ,    0.9814453...],
                          [ 532.        ,    0.9766885...],
                          [ 533.        ,    0.9709363...],
                          [ 534.        ,    0.9648947...],
                          [ 535.        ,    0.9585832...],
                          [ 536.        ,    0.952012 ...],
                          [ 537.        ,    0.9444916...],
                          [ 538.        ,    0.9367089...],
                          [ 539.        ,    0.9293506...],
                          [ 540.        ,    0.9210429...],
                          [ 541.        ,    0.9124772...],
                          [ 542.        ,    0.9036604...],
                          [ 543.        ,    0.8945958...],
                          [ 544.        ,    0.8845999...],
                          [ 545.        ,    0.8750500...],
                          [ 546.        ,    0.8659457...],
                          [ 547.        ,    0.8559224...],
                          [ 548.        ,    0.8456846...],
                          [ 549.        ,    0.8352499...],
                          [ 550.        ,    0.8253229...],
                          [ 551.        ,    0.8152079...],
                          [ 552.        ,    0.8042205...],
                          [ 553.        ,    0.7944209...],
                          [ 554.        ,    0.7837466...],
                          [ 555.        ,    0.7735680...],
                          [ 556.        ,    0.7627808...],
                          [ 557.        ,    0.7522710...],
                          [ 558.        ,    0.7417549...],
                          [ 559.        ,    0.7312909...],
                          [ 560.        ,    0.7207983...],
                          [ 561.        ,    0.7101939...],
                          [ 562.        ,    0.6996362...],
                          [ 563.        ,    0.6890656...],
                          [ 564.        ,    0.6785599...],
                          [ 565.        ,    0.6680593...],
                          [ 566.        ,    0.6575697...],
                          [ 567.        ,    0.6471578...],
                          [ 568.        ,    0.6368208...],
                          [ 569.        ,    0.6264871...],
                          [ 570.        ,    0.6161541...],
                          [ 571.        ,    0.6058896...],
                          [ 572.        ,    0.5957000...],
                          [ 573.        ,    0.5855937...],
                          [ 574.        ,    0.5754412...],
                          [ 575.        ,    0.5653883...],
                          [ 576.        ,    0.5553742...],
                          [ 577.        ,    0.5454680...],
                          [ 578.        ,    0.5355972...],
                          [ 579.        ,    0.5258267...],
                          [ 580.        ,    0.5160152...],
                          [ 581.        ,    0.5062322...],
                          [ 582.        ,    0.4965595...],
                          [ 583.        ,    0.4868746...],
                          [ 584.        ,    0.4773299...],
                          [ 585.        ,    0.4678028...],
                          [ 586.        ,    0.4583704...],
                          [ 587.        ,    0.4489722...],
                          [ 588.        ,    0.4397606...],
                          [ 589.        ,    0.4306131...],
                          [ 590.        ,    0.4215446...],
                          [ 591.        ,    0.4125681...],
                          [ 592.        ,    0.4037550...],
                          [ 593.        ,    0.3950359...],
                          [ 594.        ,    0.3864104...],
                          [ 595.        ,    0.3778777...],
                          [ 596.        ,    0.3694405...],
                          [ 597.        ,    0.3611074...],
                          [ 598.        ,    0.3528596...],
                          [ 599.        ,    0.3447056...],
                          [ 600.        ,    0.3366470...],
                          [ 601.        ,    0.3286917...],
                          [ 602.        ,    0.3208410...],
                          [ 603.        ,    0.3130808...],
                          [ 604.        ,    0.3054105...],
                          [ 605.        ,    0.2978225...],
                          [ 606.        ,    0.2903027...],
                          [ 607.        ,    0.2828727...],
                          [ 608.        ,    0.2755311...],
                          [ 609.        ,    0.2682900...],
                          [ 610.        ,    0.2611478...],
                          [ 611.        ,    0.2541176...],
                          [ 612.        ,    0.2471885...],
                          [ 613.        ,    0.2403570...],
                          [ 614.        ,    0.2336057...],
                          [ 615.        ,    0.2269379...],
                          [ 616.        ,    0.2203527...],
                          [ 617.        ,    0.2138465...],
                          [ 618.        ,    0.2073946...],
                          [ 619.        ,    0.2009789...],
                          [ 620.        ,    0.1945818...],
                          [ 621.        ,    0.1881943...],
                          [ 622.        ,    0.1818226...],
                          [ 623.        ,    0.1754987...],
                          [ 624.        ,    0.1692476...],
                          [ 625.        ,    0.1630876...],
                          [ 626.        ,    0.1570257...],
                          [ 627.        ,    0.151071 ...],
                          [ 628.        ,    0.1452469...],
                          [ 629.        ,    0.1395845...],
                          [ 630.        ,    0.1341087...],
                          [ 631.        ,    0.1288408...],
                          [ 632.        ,    0.1237666...],
                          [ 633.        ,    0.1188631...],
                          [ 634.        ,    0.1141075...],
                          [ 635.        ,    0.1094766...],
                          [ 636.        ,    0.1049613...],
                          [ 637.        ,    0.1005679...],
                          [ 638.        ,    0.0962924...],
                          [ 639.        ,    0.0921296...],
                          [ 640.        ,    0.0880778...],
                          [ 641.        ,    0.0841306...],
                          [ 642.        ,    0.0802887...],
                          [ 643.        ,    0.0765559...],
                          [ 644.        ,    0.0729367...],
                          [ 645.        ,    0.0694345...],
                          [ 646.        ,    0.0660491...],
                          [ 647.        ,    0.0627792...],
                          [ 648.        ,    0.0596278...],
                          [ 649.        ,    0.0565970...],
                          [ 650.        ,    0.0536896...],
                          [ 651.        ,    0.0509068...],
                          [ 652.        ,    0.0482444...],
                          [ 653.        ,    0.0456951...],
                          [ 654.        ,    0.0432510...],
                          [ 655.        ,    0.0409052...],
                          [ 656.        ,    0.0386537...],
                          [ 657.        ,    0.0364955...],
                          [ 658.        ,    0.0344285...],
                          [ 659.        ,    0.0324501...],
                          [ 660.        ,    0.0305579...],
                          [ 661.        ,    0.0287496...],
                          [ 662.        ,    0.0270233...],
                          [ 663.        ,    0.0253776...],
                          [ 664.        ,    0.0238113...],
                          [ 665.        ,    0.0223226...],
                          [ 666.        ,    0.0209086...],
                          [ 667.        ,    0.0195688...],
                          [ 668.        ,    0.0183056...],
                          [ 669.        ,    0.0171216...],
                          [ 670.        ,    0.0160192...],
                          [ 671.        ,    0.0149986...],
                          [ 672.        ,    0.0140537...],
                          [ 673.        ,    0.0131784...],
                          [ 674.        ,    0.0123662...],
                          [ 675.        ,    0.0116107...],
                          [ 676.        ,    0.0109098...],
                          [ 677.        ,    0.0102587...],
                          [ 678.        ,    0.0096476...],
                          [ 679.        ,    0.0090665...],
                          [ 680.        ,    0.0085053...],
                          [ 681.        ,    0.0079567...],
                          [ 682.        ,    0.0074229...],
                          [ 683.        ,    0.0069094...],
                          [ 684.        ,    0.0064213...],
                          [ 685.        ,    0.0059637...],
                          [ 686.        ,    0.0055377...],
                          [ 687.        ,    0.0051402...],
                          [ 688.        ,    0.00477  ...],
                          [ 689.        ,    0.0044263...],
                          [ 690.        ,    0.0041081...],
                          [ 691.        ,    0.0038149...],
                          [ 692.        ,    0.0035456...],
                          [ 693.        ,    0.0032984...],
                          [ 694.        ,    0.0030718...],
                          [ 695.        ,    0.0028639...],
                          [ 696.        ,    0.0026738...],
                          [ 697.        ,    0.0025000...],
                          [ 698.        ,    0.0023401...],
                          [ 699.        ,    0.0021918...],
                          [ 700.        ,    0.0020526...],
                          [ 701.        ,    0.0019207...],
                          [ 702.        ,    0.001796 ...],
                          [ 703.        ,    0.0016784...],
                          [ 704.        ,    0.0015683...],
                          [ 705.        ,    0.0014657...],
                          [ 706.        ,    0.0013702...],
                          [ 707.        ,    0.001281 ...],
                          [ 708.        ,    0.0011976...],
                          [ 709.        ,    0.0011195...],
                          [ 710.        ,    0.0010464...],
                          [ 711.        ,    0.0009776...],
                          [ 712.        ,    0.0009131...],
                          [ 713.        ,    0.0008525...],
                          [ 714.        ,    0.0007958...],
                          [ 715.        ,    0.0007427...],
                          [ 716.        ,    0.0006929...],
                          [ 717.        ,    0.0006462...],
                          [ 718.        ,    0.0006026...],
                          [ 719.        ,    0.0005619...],
                          [ 720.        ,    0.0005240...],
                          [ 721.        ,    0.0004888...],
                          [ 722.        ,    0.0004561...],
                          [ 723.        ,    0.0004255...],
                          [ 724.        ,    0.0003971...],
                          [ 725.        ,    0.0003704...],
                          [ 726.        ,    0.0003455...],
                          [ 727.        ,    0.0003221...],
                          [ 728.        ,    0.0003001...],
                          [ 729.        ,    0.0002796...],
                          [ 730.        ,    0.0002604...],
                          [ 731.        ,    0.0002423...],
                          [ 732.        ,    0.0002254...],
                          [ 733.        ,    0.0002095...],
                          [ 734.        ,    0.0001947...],
                          [ 735.        ,    0.0001809...],
                          [ 736.        ,    0.0001680...],
                          [ 737.        ,    0.0001560...],
                          [ 738.        ,    0.0001449...],
                          [ 739.        ,    0.0001345...],
                          [ 740.        ,    0.0001249...],
                          [ 741.        ,    0.0001159...],
                          [ 742.        ,    0.0001076...],
                          [ 743.        ,    0.0000999...],
                          [ 744.        ,    0.0000927...],
                          [ 745.        ,    0.0000862...],
                          [ 746.        ,    0.0000801...],
                          [ 747.        ,    0.0000745...],
                          [ 748.        ,    0.0000693...],
                          [ 749.        ,    0.0000646...],
                          [ 750.        ,    0.0000602...],
                          [ 751.        ,    0.0000561...],
                          [ 752.        ,    0.0000523...],
                          [ 753.        ,    0.0000488...],
                          [ 754.        ,    0.0000456...],
                          [ 755.        ,    0.0000425...],
                          [ 756.        ,    0.0000397...],
                          [ 757.        ,    0.0000370...],
                          [ 758.        ,    0.0000346...],
                          [ 759.        ,    0.0000322...],
                          [ 760.        ,    0.0000301...],
                          [ 761.        ,    0.0000281...],
                          [ 762.        ,    0.0000262...],
                          [ 763.        ,    0.0000244...],
                          [ 764.        ,    0.0000228...],
                          [ 765.        ,    0.0000213...],
                          [ 766.        ,    0.0000198...],
                          [ 767.        ,    0.0000185...],
                          [ 768.        ,    0.0000173...],
                          [ 769.        ,    0.0000161...],
                          [ 770.        ,    0.0000150...],
                          [ 771.        ,    0.0000140...],
                          [ 772.        ,    0.0000131...],
                          [ 773.        ,    0.0000122...],
                          [ 774.        ,    0.0000114...],
                          [ 775.        ,    0.0000106...],
                          [ 776.        ,    0.0000099...],
                          [ 777.        ,    0.0000092...],
                          [ 778.        ,    0.0000086...],
                          [ 779.        ,    0.0000080...],
                          [ 780.        ,    0.0000075...]],
                         interpolator=SpragueInterpolator,
                         interpolator_args={},
                         extrapolator=Extrapolator,
                         extrapolator_args={...})
    """

    photopic_lef_shape = photopic_lef.shape
    scotopic_lef_shape = scotopic_lef.shape
    shape = SpectralShape(
        max(photopic_lef_shape.start, scotopic_lef_shape.start),
        min(photopic_lef_shape.end, scotopic_lef_shape.end),
        max(photopic_lef_shape.interval, scotopic_lef_shape.interval))

    wavelengths = shape.range()

    sd_data = dict(
        zip(
            wavelengths,
            mesopic_weighting_function(wavelengths, Lp, source, method,
                                       photopic_lef, scotopic_lef)))

    sd = SpectralDistribution(
        sd_data, name='{0} Lp Mesopic Luminous Efficiency Function'.format(Lp))

    return sd.normalise()
Beispiel #33
0
def mesopic_luminous_efficiency_function(
        Lp,
        source='Blue Heavy',
        method='MOVE',
        photopic_lef=PHOTOPIC_LEFS.get(
            'CIE 1924 Photopic Standard Observer'),
        scotopic_lef=SCOTOPIC_LEFS.get(
            'CIE 1951 Scotopic Standard Observer')):
    """
    Returns the mesopic luminous efficiency function :math:`V_m(\lambda)` for
    given photopic luminance :math:`L_p`.

    Parameters
    ----------
    Lp : numeric
        Photopic luminance :math:`L_p`.
    source : unicode, optional
        **{'Blue Heavy', 'Red Heavy'}**,
        Light source colour temperature.
    method : unicode, optional
        **{'MOVE', 'LRC'}**,
        Method to calculate the weighting factor.
    photopic_lef : SpectralPowerDistribution, optional
        :math:`V(\lambda)` photopic luminous efficiency function.
    scotopic_lef : SpectralPowerDistribution, optional
        :math:`V^\prime(\lambda)` scotopic luminous efficiency function.

    Returns
    -------
    SpectralPowerDistribution
        Mesopic luminous efficiency function :math:`V_m(\lambda)`.

    Examples
    --------
    >>> print(mesopic_luminous_efficiency_function(0.2))
    SpectralPowerDistribution(\
'0.2 Lp Mesopic Luminous Efficiency Function', (380.0, 780.0, 1.0))
    """

    photopic_lef_shape = photopic_lef.shape
    scotopic_lef_shape = scotopic_lef.shape
    shape = SpectralShape(
        max(photopic_lef_shape.start, scotopic_lef_shape.start),
        min(photopic_lef_shape.end, scotopic_lef_shape.end),
        max(photopic_lef_shape.interval, scotopic_lef_shape.interval))

    wavelengths = shape.range()

    spd_data = dict(zip(wavelengths,
                        mesopic_weighting_function(
                            wavelengths,
                            Lp,
                            source,
                            method,
                            photopic_lef,
                            scotopic_lef)))

    spd = SpectralPowerDistribution(
        '{0} Lp Mesopic Luminous Efficiency Function'.format(Lp),
        spd_data)

    return spd.normalise()