colour.colorimetry.lefs — Colour 0.3.0 documentation

# Source code for colour.colorimetry.lefs

    #!/usr/bin/env python
    # -*- coding: utf-8 -*-

    """
    Luminous Efficiency Functions Spectral Power Distributions
    ==========================================================

    Defines luminous efficiency functions computation related objects.

    See Also
    --------
    `Luminous Efficiency Functions IPython Notebook
    <http://nbviewer.ipython.org/github/colour-science/colour-ipython/blob/master/notebooks/colorimetry/lefs.ipynb>`_  # noqa
    colour.colorimetry.dataset.lefs,
    colour.colorimetry.spectrum.SpectralPowerDistribution

    References
    ----------
    .. [1]  http://en.wikipedia.org/wiki/Mesopic#Mesopic_weighting_function
            (Last accessed 20 June 2014)
    """

    from __future__ import division, unicode_literals

    from colour.algebra import closest
    from colour.colorimetry import (
        SpectralShape,
        SpectralPowerDistribution,
        PHOTOPIC_LEFS,
        SCOTOPIC_LEFS)
    from colour.colorimetry.dataset.lefs import MESOPIC_X_DATA

    __author__ = 'Colour Developers'
    __copyright__ = 'Copyright (C) 2013 - 2014 - Colour Developers'
    __license__ = 'New BSD License - http://opensource.org/licenses/BSD-3-Clause'
    __maintainer__ = 'Colour Developers'
    __email__ = 'colour-science@googlegroups.com'
    __status__ = 'Production'

    __all__ = ['mesopic_weighting_function',
               'mesopic_luminous_efficiency_function']

    def mesopic_weighting_function(wavelength,
                                   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')):
        """
        Calculates the mesopic weighting function factor at given wavelength
        :math:`\lambda` using the photopic luminance :math:`L_p`.

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

        Returns
        -------
        numeric
            Mesopic weighting function factor.

        Raises
        ------
        KeyError
            If wavelength :math:`\lambda` is not available in either luminous
            efficiency function.

        Examples
        --------
        >>> mesopic_weighting_function(500, 0.2)  # doctest: +ELLIPSIS
        0.7052200...
        """

        for function in (photopic_lef, scotopic_lef):
            if function.get(wavelength) is None:
                raise KeyError(
                    ('"{0} nm" wavelength not available in "{1}" '
                     'luminous efficiency function with "{2}" shape!').format(
                        wavelength, function.name, function.shape))

        mesopic_x_luminance_values = sorted(MESOPIC_X_DATA.keys())
        index = mesopic_x_luminance_values.index(
            closest(mesopic_x_luminance_values, Lp))
        x = MESOPIC_X_DATA.get(
            mesopic_x_luminance_values[index]).get(source).get(method)

        Vm = ((1 - x) *
              scotopic_lef.get(wavelength) + x * photopic_lef.get(wavelength))

        return Vm

    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
            ('Blue Heavy', 'Red Heavy'),
            Light source colour temperature.
        method : unicode
            ('MOVE', 'LRC'),
            Method to calculate the weighting factor.
        photopic_lef : SpectralPowerDistribution
            :math:`V(\lambda)` photopic luminous efficiency function.
        scotopic_lef : SpectralPowerDistribution
            :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))

        spd_data = dict((i,
                         mesopic_weighting_function(
                             i,
                             Lp,
                             source,
                             method,
                             photopic_lef,
                             scotopic_lef))
                        for i in shape)

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

        return spd.normalise()