def spectrum_to_xyz(spec_intens, temp):
    """
    Calculate the CIE X, Y, and Z coordinates corresponding to
    a light source with spectral distribution given by  the
    function SPEC_INTENS, which is called with a series of
    wavelengths between 380 and 780 nm (the argument is
    expressed in meters), which returns emittance at  that
    wavelength in arbitrary units.  The chromaticity
    coordinates of the spectrum are returned in the x, y, and z
    arguments which respect the identity:

            x + y + z = 1.

    CIE colour matching functions xBar, yBar, and zBar for
       wavelengths from 380 through 780 nanometers, every 5
       nanometers.  For a wavelength lambda in this range:

            cie_colour_match[(lambda - 380) / 5][0] = xBar
            cie_colour_match[(lambda - 380) / 5][1] = yBar
            cie_colour_match[(lambda - 380) / 5][2] = zBar

    AH Note 2011: This next bit is kind of irrelevant on modern
    hardware. Unless you are desperate for speed.
    In which case don't use the Python version!

    To save memory, this table can be declared as floats
    rather than doubles; (IEEE) float has enough
    significant bits to represent the values. It's declared
    as a double here to avoid warnings about "conversion
    between floating-point types" from certain persnickety
    compilers. */
    """
    cie_colour_match = [[0.0014, 0.0, 0.0065], [0.0022, 0.0001, 0.0105], [
        0.0042, 0.0001, 0.0201], [0.0076, 0.0002, 0.0362], [0.0143, 0.0004,
        0.0679], [0.0232, 0.0006, 0.1102], [0.0435, 0.0012, 0.2074], [
        0.0776, 0.0022, 0.3713], [0.1344, 0.004, 0.6456], [0.2148, 0.0073, 
        1.0391], [0.2839, 0.0116, 1.3856], [0.3285, 0.0168, 1.623], [0.3483,
        0.023, 1.7471], [0.3481, 0.0298, 1.7826], [0.3362, 0.038, 1.7721],
        [0.3187, 0.048, 1.7441], [0.2908, 0.06, 1.6692], [0.2511, 0.0739, 
        1.5281], [0.1954, 0.091, 1.2876], [0.1421, 0.1126, 1.0419], [0.0956,
        0.139, 0.813], [0.058, 0.1693, 0.6162], [0.032, 0.208, 0.4652], [
        0.0147, 0.2586, 0.3533], [0.0049, 0.323, 0.272], [0.0024, 0.4073, 
        0.2123], [0.0093, 0.503, 0.1582], [0.0291, 0.6082, 0.1117], [0.0633,
        0.71, 0.0782], [0.1096, 0.7932, 0.0573], [0.1655, 0.862, 0.0422], [
        0.2257, 0.9149, 0.0298], [0.2904, 0.954, 0.0203], [0.3597, 0.9803, 
        0.0134], [0.4334, 0.995, 0.0087], [0.5121, 1.0, 0.0057], [0.5945, 
        0.995, 0.0039], [0.6784, 0.9786, 0.0027], [0.7621, 0.952, 0.0021],
        [0.8425, 0.9154, 0.0018], [0.9163, 0.87, 0.0017], [0.9786, 0.8163, 
        0.0014], [1.0263, 0.757, 0.0011], [1.0567, 0.6949, 0.001], [1.0622,
        0.631, 0.0008], [1.0456, 0.5668, 0.0006], [1.0026, 0.503, 0.0003],
        [0.9384, 0.4412, 0.0002], [0.8544, 0.381, 0.0002], [0.7514, 0.321, 
        0.0001], [0.6424, 0.265, 0.0], [0.5419, 0.217, 0.0], [0.4479, 0.175,
        0.0], [0.3608, 0.1382, 0.0], [0.2835, 0.107, 0.0], [0.2187, 0.0816,
        0.0], [0.1649, 0.061, 0.0], [0.1212, 0.0446, 0.0], [0.0874, 0.032, 
        0.0], [0.0636, 0.0232, 0.0], [0.0468, 0.017, 0.0], [0.0329, 0.0119,
        0.0], [0.0227, 0.0082, 0.0], [0.0158, 0.0057, 0.0], [0.0114, 0.0041,
        0.0], [0.0081, 0.0029, 0.0], [0.0058, 0.0021, 0.0], [0.0041, 0.0015,
        0.0], [0.0029, 0.001, 0.0], [0.002, 0.0007, 0.0], [0.0014, 0.0005, 
        0.0], [0.001, 0.0004, 0.0], [0.0007, 0.0002, 0.0], [0.0005, 0.0002,
        0.0], [0.0003, 0.0001, 0.0], [0.0002, 0.0001, 0.0], [0.0002, 0.0001,
        0.0], [0.0001, 0.0, 0.0], [0.0001, 0.0, 0.0], [0.0001, 0.0, 0.0], [
        0.0, 0.0, 0.0]]
    X = 0
    Y = 0
    Z = 0
    for i, lamb in enumerate(range(380, 780, 5)):
        Me = spec_intens(lamb, temp)
        X += Me * cie_colour_match[i][0]
        Y += Me * cie_colour_match[i][1]
        Z += Me * cie_colour_match[i][2]
    XYZ = X + Y + Z
    x = X / XYZ
    y = Y / XYZ
    z = Z / XYZ
    return x, y, z
